NodeJS 检查存储在本地存储器中的JWT令牌过期状态的最佳方法

nx7onnlm  于 2022-12-29  发布在  Node.js
关注(0)|答案(3)|浏览(303)

我想检查客户端的令牌是否过期。
我的令牌存储在本地存储中。
现在我要做的是:我调用服务器来检查它是否有效,但我只在路径为:第一个月
代码:

useEffect(() => {
    verifyToken(auth.token).then((res) => {
      if (res.status !== 'success' && res.message === 'Token expired') {
        signoutClient(() => {
          router.push('/auth/login');
        });
      }
    });
  }, [auth.token, router]);

现在的问题是,如果用户直接转到另一个url exp:https:exp.com/helloworld
我想用插座,但我不知道它是否可以工作。
想法是:客户端保持侦听状态,每当令牌过期时,服务器发出一条消息。
你知道我该怎么做吗?

rnmwe5a2

rnmwe5a21#

有不同的技术。

  • 请注意,在两台不同的计算机上处理时间(在本例中为过期)可能会导致时间抖动或时钟未对齐问题,因此这不是一个简单的过程 *
被动呼气

我最喜欢的模式是有一个专门的服务器错误。
当令牌过期时,服务器应响应一个特定的错误(由于角色访问而与401 Unauthorized不同)。然后,向客户机添加一个HTTP中间件,该中间件:

  • 检测到此错误响应
  • 删除本地令牌并导航到/auth/login

或者,如果您有renew token

  • 检测到此错误响应
  • 尝试更新JWT
  • 成功时重复原始请求,失败时导航到身份验证页面。
  • 这是一个被动系统,允许您将JWT视为一个模糊的字符串,并且不存在与时间相关的问题。*
返回单独的字段

如果出于安全原因,您希望在会话过期时隐藏敏感信息,即使用户没有与UI交互(如银行网站),您需要知道令牌何时过期。一种常见的技术是将过期时间与令牌一起返回(在身份验证响应中)。

{
   "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.JFDV4mOKKh0sMfkBKvsbvm8iWjHEGBXtPvC49ob3qiI",
   "expiresAt": 1234567890
}

或者更好

{
   "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.JFDV4mOKKh0sMfkBKvsbvm8iWjHEGBXtPvC49ob3qiI",
   "expiresIn": 600
}
  • 第一个选项返回相对于服务器时间的UNIX令牌到期时间。这会受到时间抖动或时钟偏差的影响(这可能会导致错误)。第二个选项更好,因为它让UI知道令牌将在多少秒内到期(自收到响应后),然后可以使用它根据本地时钟计算UNIX时间。*
  • 通常从expiresAtexpiresIn中移除一小段时间步长,以避免时钟抖动和时钟漂移问题。*
解析JWT

如果您没有其他解决方案,您可以随时解析JWT

const JWT = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEyMzQ1Njc4OTAsIm5hbWUiOiJKb2huIERvZSIsImlhdCI6MTUxNjIzOTAyMn0.1c_yQjnMZfKUb4UTDE_WvbC71f8xxtyMsdqKKkI1hF8`;

const jwtPayload = JSON.parse(window.atob(JWT.split('.')[1]))
console.log(jwtPayload.exp);
tktrz96b

tktrz96b2#

您可以使用一个库(如jwt_decode)来解码您的JWT令牌,其中它很可能包含一个您可以检查的过期时间戳(将其与当前时间戳进行比较),如果过期,只需将其从本地存储中删除,并将用户重定向到登录页面。
但您还必须考虑为调用API以检查任何401响应状态代码的函数添加一个catch块,以便执行相同的操作(如果令牌有效,则当用户在其到期日期附近移动时)

gpnt7bae

gpnt7bae3#

如果您使用的是Axios库,则可以使用拦截器来检查令牌过期,这样就可以放入一个请求,处理从后端API检索新的JWT令牌。

相关问题