node jwt: How can I send a new token when the old one expires?
up vote
0
down vote
favorite
I'm working on a game that requires the user to sign in, so I send a token with an expiry of 24 hours so the user doesn't have to sign in.
My understanding (and possibly, handling) of the tokens is crude, but so far it does what I need it to (allows user to auto-login by submitting the token, can't access most of the APIs without a valid token, and forces the user to log in after 24 hrs).
However, I ran into an issue that while playing the game and submitting my score, the token expired, and thus was prevented from updating my score.
So I thought why not issue a new one when it is expired? Perhaps the APIs can take that expired token and issue a new one? Well, I tried.
Here's my code so far:
signToken: function(p_userId, p_isRefresh) {
return new Promise((resolve, reject) => {
const tokenUuid = uuidv4();
const connection = dbConnMysql.createConnection();
dbConnMysql.startConnection(connection).then(() => {
// Adds user ID, UUID, and expiry to DB
}).then(() => {
return dbConnMysql.closeConnection(connection).then(() => {
const payload = {
'id':p_userId,
'uuid':tokenUuid
};
let token = jwt.sign(payload, appcfg['tkSecret'], {expiresIn: 120}); //86400 for 24 hrs
var response = {};
if (!p_isRefresh || p_isRefresh === null) {
response = {'token':token};
} else if (p_isRefresh) {
let tokenStatus = {'isValid':true, 'reason':"Token Valid", 'id':p_userId, 'uuid':tokenUuid, 'token':token};
var response = {'statusCode': 200, 'message': JSON.stringify(tokenStatus)};
}
resolve(response);
});
}).catch((error) => {
// Error Handling
});
});
},
validateToken: function(p_token, p_isActive) {
return new Promise((resolve, reject) => {
let decodedToken = jwt.verify(p_token, appcfg['tkSecret']);
let dateNow = new Date();
if (decodedToken.exp > dateNow.getTime() / 1000) {
const connection = dbConnMysql.createConnection();
dbConnMysql.startConnection(connection).then(() => {
// Checks if UUID is in DB
}).then((fulfilled) => {
return dbConnMysql.closeConnection(connection)
.then(() => {
// If UUID is in DB, resolve with token, else, reject with message 'Token not valid'
})
.catch((error) => {
// Error Handling
});
})
} else {
if (!p_isActive) {
// Token was not in use when it became invalid, reject. Deletes entry in DB.
} else {
// Token was in use when it became invalid, create a new one.
dbConnMysql.startConnection(connection).then(() => {
// Delete expired token
}).then(() => {
return this.signToken(decodedToken.id, true);
});
}
}
});
}
My problem is that it doesn't even bother checking the database; once the code line
let decodedToken = jwt.verify(p_token, appcfg['tkSecret']);
is hit, it throws an error, saying the token is expired, seemingly* making the rest of my code useless. I'm wondering what the simplest work around or solution is to this problem; as much as I'd like to delve into solutions that I would need to read up on and study (such as sending refresh tokens), I am pressed for time, and the game itself is rather rigid and hard to change as of now.
A possible solution that I can think of is that instead of issuing a new token when the old one is expired, I could issue a new one X hours / minutes / seconds before it actually does, but that (probably) has its own set of problems, so I'm open to hearing other ideas.
Or... why does it completely break the code when the token is expired?
*I console logged out every catch and then block, but near as I can tell, it's the outer-most catch catches the error with this:
TokenExpiredError: jwt expired
Thanks.
node.js promise jwt
add a comment |
up vote
0
down vote
favorite
I'm working on a game that requires the user to sign in, so I send a token with an expiry of 24 hours so the user doesn't have to sign in.
My understanding (and possibly, handling) of the tokens is crude, but so far it does what I need it to (allows user to auto-login by submitting the token, can't access most of the APIs without a valid token, and forces the user to log in after 24 hrs).
However, I ran into an issue that while playing the game and submitting my score, the token expired, and thus was prevented from updating my score.
So I thought why not issue a new one when it is expired? Perhaps the APIs can take that expired token and issue a new one? Well, I tried.
Here's my code so far:
signToken: function(p_userId, p_isRefresh) {
return new Promise((resolve, reject) => {
const tokenUuid = uuidv4();
const connection = dbConnMysql.createConnection();
dbConnMysql.startConnection(connection).then(() => {
// Adds user ID, UUID, and expiry to DB
}).then(() => {
return dbConnMysql.closeConnection(connection).then(() => {
const payload = {
'id':p_userId,
'uuid':tokenUuid
};
let token = jwt.sign(payload, appcfg['tkSecret'], {expiresIn: 120}); //86400 for 24 hrs
var response = {};
if (!p_isRefresh || p_isRefresh === null) {
response = {'token':token};
} else if (p_isRefresh) {
let tokenStatus = {'isValid':true, 'reason':"Token Valid", 'id':p_userId, 'uuid':tokenUuid, 'token':token};
var response = {'statusCode': 200, 'message': JSON.stringify(tokenStatus)};
}
resolve(response);
});
}).catch((error) => {
// Error Handling
});
});
},
validateToken: function(p_token, p_isActive) {
return new Promise((resolve, reject) => {
let decodedToken = jwt.verify(p_token, appcfg['tkSecret']);
let dateNow = new Date();
if (decodedToken.exp > dateNow.getTime() / 1000) {
const connection = dbConnMysql.createConnection();
dbConnMysql.startConnection(connection).then(() => {
// Checks if UUID is in DB
}).then((fulfilled) => {
return dbConnMysql.closeConnection(connection)
.then(() => {
// If UUID is in DB, resolve with token, else, reject with message 'Token not valid'
})
.catch((error) => {
// Error Handling
});
})
} else {
if (!p_isActive) {
// Token was not in use when it became invalid, reject. Deletes entry in DB.
} else {
// Token was in use when it became invalid, create a new one.
dbConnMysql.startConnection(connection).then(() => {
// Delete expired token
}).then(() => {
return this.signToken(decodedToken.id, true);
});
}
}
});
}
My problem is that it doesn't even bother checking the database; once the code line
let decodedToken = jwt.verify(p_token, appcfg['tkSecret']);
is hit, it throws an error, saying the token is expired, seemingly* making the rest of my code useless. I'm wondering what the simplest work around or solution is to this problem; as much as I'd like to delve into solutions that I would need to read up on and study (such as sending refresh tokens), I am pressed for time, and the game itself is rather rigid and hard to change as of now.
A possible solution that I can think of is that instead of issuing a new token when the old one is expired, I could issue a new one X hours / minutes / seconds before it actually does, but that (probably) has its own set of problems, so I'm open to hearing other ideas.
Or... why does it completely break the code when the token is expired?
*I console logged out every catch and then block, but near as I can tell, it's the outer-most catch catches the error with this:
TokenExpiredError: jwt expired
Thanks.
node.js promise jwt
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I'm working on a game that requires the user to sign in, so I send a token with an expiry of 24 hours so the user doesn't have to sign in.
My understanding (and possibly, handling) of the tokens is crude, but so far it does what I need it to (allows user to auto-login by submitting the token, can't access most of the APIs without a valid token, and forces the user to log in after 24 hrs).
However, I ran into an issue that while playing the game and submitting my score, the token expired, and thus was prevented from updating my score.
So I thought why not issue a new one when it is expired? Perhaps the APIs can take that expired token and issue a new one? Well, I tried.
Here's my code so far:
signToken: function(p_userId, p_isRefresh) {
return new Promise((resolve, reject) => {
const tokenUuid = uuidv4();
const connection = dbConnMysql.createConnection();
dbConnMysql.startConnection(connection).then(() => {
// Adds user ID, UUID, and expiry to DB
}).then(() => {
return dbConnMysql.closeConnection(connection).then(() => {
const payload = {
'id':p_userId,
'uuid':tokenUuid
};
let token = jwt.sign(payload, appcfg['tkSecret'], {expiresIn: 120}); //86400 for 24 hrs
var response = {};
if (!p_isRefresh || p_isRefresh === null) {
response = {'token':token};
} else if (p_isRefresh) {
let tokenStatus = {'isValid':true, 'reason':"Token Valid", 'id':p_userId, 'uuid':tokenUuid, 'token':token};
var response = {'statusCode': 200, 'message': JSON.stringify(tokenStatus)};
}
resolve(response);
});
}).catch((error) => {
// Error Handling
});
});
},
validateToken: function(p_token, p_isActive) {
return new Promise((resolve, reject) => {
let decodedToken = jwt.verify(p_token, appcfg['tkSecret']);
let dateNow = new Date();
if (decodedToken.exp > dateNow.getTime() / 1000) {
const connection = dbConnMysql.createConnection();
dbConnMysql.startConnection(connection).then(() => {
// Checks if UUID is in DB
}).then((fulfilled) => {
return dbConnMysql.closeConnection(connection)
.then(() => {
// If UUID is in DB, resolve with token, else, reject with message 'Token not valid'
})
.catch((error) => {
// Error Handling
});
})
} else {
if (!p_isActive) {
// Token was not in use when it became invalid, reject. Deletes entry in DB.
} else {
// Token was in use when it became invalid, create a new one.
dbConnMysql.startConnection(connection).then(() => {
// Delete expired token
}).then(() => {
return this.signToken(decodedToken.id, true);
});
}
}
});
}
My problem is that it doesn't even bother checking the database; once the code line
let decodedToken = jwt.verify(p_token, appcfg['tkSecret']);
is hit, it throws an error, saying the token is expired, seemingly* making the rest of my code useless. I'm wondering what the simplest work around or solution is to this problem; as much as I'd like to delve into solutions that I would need to read up on and study (such as sending refresh tokens), I am pressed for time, and the game itself is rather rigid and hard to change as of now.
A possible solution that I can think of is that instead of issuing a new token when the old one is expired, I could issue a new one X hours / minutes / seconds before it actually does, but that (probably) has its own set of problems, so I'm open to hearing other ideas.
Or... why does it completely break the code when the token is expired?
*I console logged out every catch and then block, but near as I can tell, it's the outer-most catch catches the error with this:
TokenExpiredError: jwt expired
Thanks.
node.js promise jwt
I'm working on a game that requires the user to sign in, so I send a token with an expiry of 24 hours so the user doesn't have to sign in.
My understanding (and possibly, handling) of the tokens is crude, but so far it does what I need it to (allows user to auto-login by submitting the token, can't access most of the APIs without a valid token, and forces the user to log in after 24 hrs).
However, I ran into an issue that while playing the game and submitting my score, the token expired, and thus was prevented from updating my score.
So I thought why not issue a new one when it is expired? Perhaps the APIs can take that expired token and issue a new one? Well, I tried.
Here's my code so far:
signToken: function(p_userId, p_isRefresh) {
return new Promise((resolve, reject) => {
const tokenUuid = uuidv4();
const connection = dbConnMysql.createConnection();
dbConnMysql.startConnection(connection).then(() => {
// Adds user ID, UUID, and expiry to DB
}).then(() => {
return dbConnMysql.closeConnection(connection).then(() => {
const payload = {
'id':p_userId,
'uuid':tokenUuid
};
let token = jwt.sign(payload, appcfg['tkSecret'], {expiresIn: 120}); //86400 for 24 hrs
var response = {};
if (!p_isRefresh || p_isRefresh === null) {
response = {'token':token};
} else if (p_isRefresh) {
let tokenStatus = {'isValid':true, 'reason':"Token Valid", 'id':p_userId, 'uuid':tokenUuid, 'token':token};
var response = {'statusCode': 200, 'message': JSON.stringify(tokenStatus)};
}
resolve(response);
});
}).catch((error) => {
// Error Handling
});
});
},
validateToken: function(p_token, p_isActive) {
return new Promise((resolve, reject) => {
let decodedToken = jwt.verify(p_token, appcfg['tkSecret']);
let dateNow = new Date();
if (decodedToken.exp > dateNow.getTime() / 1000) {
const connection = dbConnMysql.createConnection();
dbConnMysql.startConnection(connection).then(() => {
// Checks if UUID is in DB
}).then((fulfilled) => {
return dbConnMysql.closeConnection(connection)
.then(() => {
// If UUID is in DB, resolve with token, else, reject with message 'Token not valid'
})
.catch((error) => {
// Error Handling
});
})
} else {
if (!p_isActive) {
// Token was not in use when it became invalid, reject. Deletes entry in DB.
} else {
// Token was in use when it became invalid, create a new one.
dbConnMysql.startConnection(connection).then(() => {
// Delete expired token
}).then(() => {
return this.signToken(decodedToken.id, true);
});
}
}
});
}
My problem is that it doesn't even bother checking the database; once the code line
let decodedToken = jwt.verify(p_token, appcfg['tkSecret']);
is hit, it throws an error, saying the token is expired, seemingly* making the rest of my code useless. I'm wondering what the simplest work around or solution is to this problem; as much as I'd like to delve into solutions that I would need to read up on and study (such as sending refresh tokens), I am pressed for time, and the game itself is rather rigid and hard to change as of now.
A possible solution that I can think of is that instead of issuing a new token when the old one is expired, I could issue a new one X hours / minutes / seconds before it actually does, but that (probably) has its own set of problems, so I'm open to hearing other ideas.
Or... why does it completely break the code when the token is expired?
*I console logged out every catch and then block, but near as I can tell, it's the outer-most catch catches the error with this:
TokenExpiredError: jwt expired
Thanks.
node.js promise jwt
node.js promise jwt
asked Nov 14 at 11:14
zack_falcon
1,526124176
1,526124176
add a comment |
add a comment |
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53298930%2fnode-jwt-how-can-i-send-a-new-token-when-the-old-one-expires%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown