Ответ 1
Это ответ, если кто-то хочет знать
if (Date.now() >= exp * 1000) {
return false;
}
Я настроил токен следующим образом:
jwt.sign(
{
user: pick(user, ['_id', 'username'])
},
secret,
{
expiresIn: '2m'
}
);
Но когда я хочу проверить, истек ли токен, этот код не работает
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;
}
Проблема в этой части:
if (exp < (new Date().getTime() + 1) / 1000) {
return false;
}
new Date(). getTime() + 1)/1000 = 1531335468.113
exp = 1531334595
Потому что я не знаю, какой формат времени использует JWT...
Как я могу это решить?
Спасибо!
Это ответ, если кто-то хочет знать
if (Date.now() >= exp * 1000) {
return false;
}
Вам следует использовать jwt.verify, чтобы проверить, не истек ли токен. jwt.decode не следует использовать, если источник не является доверенным, поскольку он не проверяет, является ли токен действительным.
verify
сам возвращает ошибку, если истек срок ее действия. Безопаснее, как сказал @Габриэль.
const jwt = require('jsonwebtoken')
router.use(asyncWrap (async (req, res, next) => {
let token = jwtService.getBearerToken(req)
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()
});
}))
К сожалению, у ответа Андреса Монтойи есть недостаток, связанный с тем, как он сравнивает объект. Я нашел решение здесь, которые должны решить эту проблему:
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)}')
}
Спасибо Джонфриману!