简体   繁体   English

使用此 JWT 库检查令牌是否过期

[英]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!有些答案省略了超级危险的验证步骤!

safe replacement for jwt.verify with following changes安全更换jwt.verify并进行以下更改

  • it does NOT throw when token is expired, but does throw for invalid token.不会在令牌过期时抛出,但会抛出无效令牌。
  • return object is {payload, expired} instead of payload返回 object 是{payload, expired}而不是payload

js version js版本

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;
  }
}

ts version ts版本

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.

相关问题 使用JWT令牌使访问令牌过期时刷新令牌调用 - Refresh Token call when Access token expired using JWT token Twilio JWT令牌已过期 - Twilio JWT Token expired 使用 Axios 拦截器和 httpOnly cookies 请求自动刷新过期 JWT 令牌的正确工作流程 - Proper workflow for refreshing expired JWT token automatically on request using Axios interceptor and httpOnly cookies 如何在不使用库的情况下在 javascript 中解码 jwt 令牌? - How to decode jwt token in javascript without using a library? 使用Angular Interceptor的JWT过期令牌处理不断刷新 - JWT expired token handling with Angular Interceptor keeps refreshing 当 jwt 刷新令牌未过期时,React Native 应用程序注销 - React Native app logs out when jwt refresh token is not expired 如何检查身份验证令牌是否已过期并强制注销? - How to check if auth token is expired and force logout? 在节点中解码 Jwt 令牌 - 没有库 - Decode Jwt Token in Node - without Library 如何在不使用库的情况下在本机 Javascript 中验证 Azure OAuth 访问 JWT 令牌? - How to verify an Azure OAuth Access JWT Token in native Javascript without using a library? 如何使用带有 nodejs 的异步 function 路由检查 JWT 令牌是否有效? - How can i check a JWT token is valid using an async function route with nodejs?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM