简体   繁体   English

如果存储在本地存储中,检查 jwt 令牌过期状态的最佳方法

[英]Best way to check jwt token expire status if stored in localstorage

I want to check if the token is expired on client side.我想检查令牌是否在客户端过期。

My token is stored in localstorage.我的令牌存储在本地存储中。

Now what I do is: make a call to the server to check if it is valid but I only do it when the path is: https:exp.com/现在我要做的是:调用服务器以检查它是否有效,但我只在路径为: https:exp.com/时才这样做

code:代码:

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

Now the problem here is what if the user goes directly to another url exp: https:exp.com/helloworld现在这里的问题是如果用户直接转到另一个 url exp: https:exp.com/helloworld

I was thinking to use sockets but I don't know if it could work.我正在考虑使用 sockets,但我不知道它是否可行。

Idea is: client stays in listen, whenever token expires server emits a message.想法是:只要令牌过期,客户端就会保持监听状态,服务器会发出一条消息。

Any idea on how can I do it?关于我该怎么做的任何想法?

There are different techniques.有不同的技术。

Note that handling time on two different machines (expiration in this case) may lead to issues due to time jitter or clock misalignment, so it is not so straight forward请注意,在两台不同的机器上处理时间(在这种情况下是过期)可能会由于时间抖动或时钟错位而导致问题,所以它不是那么直截了当

Passive expiration被动到期

My favorite pattern is to have a dedicated server error.我最喜欢的模式是出现专用服务器错误。

Your server should respond with a particular error when the token is expired (to be distinguished from the 401 Unauthorized due to role access).当令牌过期时,您的服务器应响应特定错误(与401 Unauthorized由于角色访问区分开来)。 You then add an HTTP middleware to your client that:然后,您将 HTTP 中间件添加到您的客户端:

  • detects this error response检测到此错误响应
  • deletes local token and navigates to /auth/login删除本地令牌并导航到/auth/login

Or if you have a renew token :或者,如果您有renew token

  • detects this error response检测到此错误响应
  • attempts to renew the JWT尝试更新JWT
  • repeats the original request on success OR navigates to auth page on failure.成功时重复原始请求或失败时导航到身份验证页面。

This is a passive system that allows you to treat the JWT as an obscure string and does not have time-related issues.这是一个被动系统,允许您将JWT视为晦涩的字符串,并且不存在与时间相关的问题。

Return a separate field返回一个单独的字段

If, for security reasons, you want to hide sensible information when the session expires even when the user is not interacting with the UI (like Banking sites do) you need to know when the token will expire .如果出于安全原因,您想在 session 过期时隐藏敏感信息,即使用户没有与 UI 交互(如银行网站那样),您需要知道令牌何时过期 A common technique is to return expiration time together with the token (within the authentication response).一种常见的技术是将过期时间与令牌一起返回(在身份验证响应中)。

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

Or even better甚至更好

{
   "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.JFDV4mOKKh0sMfkBKvsbvm8iWjHEGBXtPvC49ob3qiI",
   "expiresIn": 600
}

The first one returns you the UNIX time of token expiration relative to server time .第一个返回 UNIX 令牌到期时间相对于服务器时间 This is subject to time jitter or clock misalignment (this may lead to errors).这会受到时间抖动或时钟失调的影响(这可能会导致错误)。 The second one is better as it lets the UI know within how many seconds (since the Response was received) the token will expire, this can be then used to calculate the UNIX time according to the local clock.第二个更好,因为它让 UI 知道令牌将在多少秒内(因为收到响应)过期,然后可以用来根据本地时钟计算 UNIX 时间。

It is common to remove a small time step from expiresAt and expiresIn to avoid clock jitter and clock drift issues.通常从expiresAtexpiresIn中删除一个小时间步,以避免时钟抖动和时钟漂移问题。

Parse the JWT解析 JWT

If you have no other solution, you can always parse the JWT :如果您没有其他解决方案,您可以随时解析JWT

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

You can use a lib(like jwt_decode ) to decode your JWT token, where it's most likely contains an expiration timestamp that you can check(compare it with the current timestamp for this moment) and if it exceeded(expired) just delete it from local storage and redirect user to login page.您可以使用 lib(如jwt_decode )来解码您的 JWT 令牌,其中很可能包含您可以检查的过期时间戳(将其与当前时间戳进行比较),如果超过(过期)只需从本地删除它存储并将用户重定向到登录页面。

But you also have to consider add a catch block for functions which calls your API to check for any 401 response status code to also do the same (in case the token was valid then while the user is moving around its expiry date ends)但是您还必须考虑为调用 API 的函数添加一个catch块,以检查是否有任何401响应状态代码也执行相同操作(如果令牌有效,那么当用户在其到期日期结束时移动)

If you are using the Axios library, you can use the interceptor to check the token expiration thus you can put in a request that handles the retrieval of a new fresh JWT token from the backend API.如果您使用的是 Axios 库,则可以使用拦截器来检查令牌过期,因此您可以放入一个请求来处理从后端 API 检索新的 JWT 令牌。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM