[英]Check if token expired using this JWT library
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新日期().getTime() + 1) / 1000 = 1531335468.113
exp = 1531334595 exp = 1531334595
Because I don't know what format of time JWT uses...因为不知道 JWT 使用什么时间格式...
How can I resolve this?我该如何解决这个问题?
This is the answer:这是答案:
if (Date.now() >= exp * 1000) {
return false;
}
You should use jwt.verify .您应该使用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.如果源不受信任,则不应使用jwt.decode ,因为它不检查令牌是否有效。
Function without the jwt
library:没有
jwt
库的函数:
Browser浏览器
function isTokenExpired(token) {
const base64Url = token.split(".")[1];
const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
const jsonPayload = decodeURIComponent(
atob(base64)
.split("")
.map(function (c) {
return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
})
.join("")
);
const { exp } = JSON.parse(jsonPayload);
const expired = Date.now() >= exp * 1000
return expired
}
Or simpler或者更简单
function isTokenExpired(token) {
const expiry = (JSON.parse(atob(token.split('.')[1]))).exp;
return (Math.floor((new Date).getTime() / 1000)) >= expiry;
}
Or a one-liner:或单线:
const isTokenExpired = token => Date.now() >= (JSON.parse(atob(token.split('.')[1]))).exp * 1000
Node.js节点.js
function isTokenExpired(token) {
const payloadBase64 = token.split('.')[1];
const decodedJson = Buffer.from(payloadBase64, 'base64').toString();
const decoded = JSON.parse(decodedJson)
const exp = decoded.exp;
const expired = (Date.now() >= exp * 1000)
return expired
}
Or a one-liner:或单线:
const isTokenExpired = (token) => (Date.now() >= JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString()).exp * 1000)
verify
itself returns an error if expired.如果过期,
verify
本身会返回错误。 It is 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()
});
})
Sadly, Andrés Montoya's answer has a flaw which is related to how he compares the object.可悲的是, 安德烈斯蒙托亚的答案有一个缺陷,这与他如何比较对象有关。
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 user thejohnfreeman !感谢用户thejohnfreeman !
The following function works without any libraries:以下函数无需任何库即可工作:
function getJWTExpireDate(jwtToken: string) {
if (jwtToken) {
try {
const [, payload] = jwtToken.split('.');
const { exp: expires } = JSON.parse(window.atob(payload));
if (typeof expires === 'number') {
return new Date(expires * 1000);
}
} catch {
// ignore
}
}
return null;
}
Don't use this to check whether the token is valid.不要使用它来检查令牌是否有效。 One good use case is displaying when the token expires in the frontend.
一个很好的用例是在前端显示令牌何时过期。
This is for React Native , but login will work for all types.这适用于React Native ,但登录适用于所有类型。
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;
}
}
You can use the jwt verify method to check the validity of your token.您可以使用jwt verify 方法来检查令牌的有效性。 err means the token is expired and will throw an error so you can remove the stored token.
err表示令牌已过期并将引发错误,因此您可以删除存储的令牌。
jwt.verify(token, SECRET, (err, decoded) => {
if (err) {
localStorage.clear();
}}
});
some answers omit verification step which is super dangerous!有些答案省略了超级危险的验证步骤!
jwt.verify
with following changesjwt.verify
并进行以下更改{payload, expired}
instead of payload
{payload, expired}
而不是payload
export function verifyJWT(token) {
try {
return { payload: jwt.verify(token, publicKey), expired: false };
} catch (error) {
if (error.name == "TokenExpiredError") {
return { payload: jwt.decode(token), expired: true };
}
throw error;
}
}
export function verifyJWT(token: string) {
try {
return { payload: jwt.verify(token, publicKey), expired: false };
} catch (error) {
if ((error as Error).name == "TokenExpiredError") {
return { payload: jwt.decode(token), expired: true };
}
throw error;
}
}
const JWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEyMzQ1Njc4OTAsIm5hbWUiOiJKb2huIERvZSIsImlhdCI6MTUxNjIzOTAyMn0.1c_yQjnMZfKUb4UTDE_WvbC71f8xxtyMsdqKKkI1hF8";
const jwtPayload = JSON.parse(window.atob(JWT.split('.')[1]))
const isExpired = Date.now() >= jwtPayload.exp * 1000;
// 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')
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.