【问题标题】:How to detect jwt token expire on React如何在 React 上检测 jwt 令牌过期
【发布时间】:2021-03-19 11:06:12
【问题描述】:

使用后端 node.js,我创建了一个具有过期时间的 JWT 令牌:

signToken = (user) => {
    return jwt.sign({ id: user.userId }, process.env.JWT_SECRET, { expiresIn: 60 * 60 * 24 * 10 }) // 1h = 60 * 60
}

使用前端的 React 应用程序,当用户登录时,我会将这个 JWT 令牌与返回数据一起传递并保存到本地存储(我正在使用 Redux):

const result = await userLogin({ username, password })
dispatch({ type: USER_LOGIN_SUCCESS, payload: result.data.data })
const { userReducer } = getState()
window.localStorage.setItem("accessToken", JSON.stringify(userReducer.token))

每个 api 都需要此令牌进行授权,我将在标头中传递此令牌。我在 axios 请求拦截器中设置:

instance.interceptors.request.use(
    (config) => {
        const accessToken = localStorage.getItem("accessToken")
        config.headers.Authorization = accessToken ? `Bearer ${accessToken}` : ""
        if (config.url.includes("/files/")) {
            config.headers["Content-Type"] = "multipart/form-data"
        }
        return config
    },
    (error) => {
        return Promise.reject(error.response)
    }
)

我的问题是如何检测令牌是否在 React 上过期。在这个 React 应用中,我使用的是 axios、redux、react-redux 和 react router。

【问题讨论】:

  • 如果令牌无效,您的 API 会返回一个错误,您能不能只使用该错误作为您需要新令牌的指示?
  • 一种方法是在localStorage 中添加令牌到期时间戳以及令牌。当令牌即将到期时,您可以执行必要的操作,例如令牌重新生成、验证等

标签: javascript reactjs jwt


【解决方案1】:

可以补充给出的答案是,假设您将 jwt 令牌设置为从现在开始持续 10 天,您将执行以下操作:10 * 24 * 60 * 60 * 1000 所以这将以毫秒为单位设置从现在开始的 10 天。

现在,当您在服务器中收到以毫秒为单位的过期令牌时,您现在要做的是,不要等待收到错误消息,但您要做的是 比较 如果令牌中的日期(在毫秒)大于当前日期,那么如果这是真的,那么你知道令牌仍然有效......

替代方案

由于您已经将 Jwt 存储在 localStorage 中,因此您可以切换到存储在 Cookie 中确实没有什么区别,但从某种意义上说,一旦令牌过期,它将从您的 cookie 存储中删除,从而使服务器验证变得容易,即如果 cookie未发送意味着它已经过期,但这仅适用于存储在 cookie 中

【讨论】:

    【解决方案2】:

    我同意 Cory 的评论,即您应该在服务器而不是客户端上进行验证。如果您想做一些基本检查,假设您的 JWT 正文未加密,以下将起作用。

    // Some fake JWT I made using an online builder
    const exampleJWT = `eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2MDc0MDc3NTYsImV4cCI6MTYzODk0Mzc1NiwiYXVkIjoid3d3LmV4YW1wbGUuY29tIiwic3ViIjoianJvY2tldEBleGFtcGxlLmNvbSIsIkdpdmVuTmFtZSI6IkpvaG5ueSIsIlN1cm5hbWUiOiJSb2NrZXQiLCJFbWFpbCI6Impyb2NrZXRAZXhhbXBsZS5jb20iLCJSb2xlIjpbIk1hbmFnZXIiLCJQcm9qZWN0IEFkbWluaXN0cmF0b3IiXX0.cfBNHOIaUSAVtLHbxlOmMZtp-giA7-v8yJpMyGooefE`;
    
    function getPayload(jwt){
      // A JWT has 3 parts separated by '.'
      // The middle part is a base64 encoded JSON
      // decode the base64 
      return atob(jwt.split(".")[1])
    }
    
    const payload = getPayload(exampleJWT);
    
    const expiration = new Date(payload.exp);
    const now = new Date();
    const fiveMinutes = 1000 * 60 * 5;
    
    if( expiration.getTime() - now.getTime() < fiveMinutes ){
      console.log("JWT has expired or will expire soon");
    } else {
      console.log("JWT is valid for more than 5 minutes", payload);
    }

    【讨论】:

    • 是的,已经有服务器端验证。我有一个中间件检测令牌是否在每个 api 端点之前工作。所以从你的意思来看,我不需要 clinet 端令牌过期检查?
    猜你喜欢
    • 2018-06-19
    • 2016-11-19
    • 2021-12-31
    • 1970-01-01
    • 2020-06-30
    • 2017-03-04
    • 2019-07-04
    • 2020-02-20
    • 2020-06-13
    相关资源
    最近更新 更多