I've configured the token like this:
jwt.sign(
{
user: pick(user, ['_id', 'username'])
},
secret,
{
expiresIn: '2m'
}
);
But when I want to check if the token was expired, this code doesn't work
function isAuthenticated() {
const token = localStorage.getItem('token');
const refreshToken = localStorage.getItem('refreshToken');
try {
decode(token);
const { exp } = decode(refreshToken);
if (exp < (new Date().getTime() + 1) / 1000) {
return false;
}
} catch (err) {
return false;
}
return true;
}
The problem is this part:
if (exp < (new Date().getTime() + 1) / 1000) {
return false;
}
new Date().getTime() + 1) / 1000 = 1531335468.113
exp = 1531334595
Because I don't know what format of time uses JWT...
How can I resolve this?
Thank you!
You should use jwt.verify it will check if the token is expired. jwt.decode should not be used if the source is not trusted as it doesn't check if the token is valid.
verify
itself returns an error if expired. Safer as @Gabriel said.
const jwt = require('jsonwebtoken')
router.use((req, res, next) => {
const token = yourJwtService.getToken(req) // Get your token from the request
jwt.verify(token, req.app.get('your-secret'), function(err, decoded) {
if (err) throw new Error(err) // Manage different errors here (Expired, untrusted...)
req.auth = decoded // If no error, token info is returned in 'decoded'
next()
});
})
And same written in async/await
syntax:
const jwt = require('jsonwebtoken')
const jwtVerifyAsync = util.promisify(jwt.verify);
router.use(async (req, res, next) => {
const token = yourJwtService.getToken(req) // Get your token from the request
try {
req.auth = await jwtVerifyAsync(token, req.app.get('your-secret')) // If no error, token info is returned
} catch (err) {
throw new Error(err) // Manage different errors here (Expired, untrusted...)
}
next()
});
This is for react-native, but login will work for all types.
isTokenExpired = async () => {
try {
const LoginTokenValue = await AsyncStorage.getItem('LoginTokenValue');
if (JSON.parse(LoginTokenValue).RememberMe) {
const { exp } = JwtDecode(LoginTokenValue);
if (exp < (new Date().getTime() + 1) / 1000) {
this.handleSetTimeout();
return false;
} else {
//Navigate inside the application
return true;
}
} else {
//Navigate to the login page
}
} catch (err) {
console.log('Spalsh -> isTokenExpired -> err', err);
//Navigate to the login page
return false;
}
}
Sadly @Andrés Montoya answer has a flaw which is related to how he compares the obj. I found a solution here which should solve this:
const now = Date.now().valueOf() / 1000
if (typeof decoded.exp !== 'undefined' && decoded.exp < now) {
throw new Error(`token expired: ${JSON.stringify(decoded)}`)
}
if (typeof decoded.nbf !== 'undefined' && decoded.nbf > now) {
throw new Error(`token expired: ${JSON.stringify(decoded)}`)
}
Thanks to thejohnfreeman!
// Pass in function expiration date to check token
function checkToken(exp) {
if (Date.now() <= exp * 1000) {
console.log(true, 'token is not expired')
} else {
console.log(false, 'token is expired')
}
}
Source: Stackoverflow.com