内存中的JWT访问令牌?

我已经在这方面花费了数小时和数小时,这是我第一次使用 JWT,真的需要您的一些想法。

现在我将我的令牌存储在单独的 httpOnly cookie 中(我的访问令牌在 15 分钟后过期,并在 7 天后刷新令牌)。

我已经读到存储令牌的最安全方法实际上是使用 cookie 作为刷新令牌和内存中(如在变量中)作为访问令牌。

虽然我知道这是安全的,但我并不真正理解它在实践中是如何工作的。这是否意味着我们必须在每个请求上使用刷新令牌创建一个新的访问令牌?或者有没有办法让它有效并复制到新变量,直到它过期?

我正在使用反应和节点 btw。

回答

我也花了几天的时间来阅读这个。从我收集到的解决方案将是这样的:

  1. 用户使用登录名和密码登录。

  2. 服务器生成一个长期存在的刷新令牌作为 HttpOnly Cookie 存储,防止 XSS 攻击,因为它不能被 Javascript 访问。

    • 理想情况下,可以在服务器端使用某种黑名单来防止重新使用尚未到期但已被替换的刷新令牌。
  3. Generate an access token which can either be stored in localStorage or in-memory (in a variable). The access token has a short expiry life of a few minutes.

    • If stored in localStorage, the token will not disappear on a reload of the page/browser (F5). It will also be visible in the console/storage.
    • When using localStorage to check if user is authenticated, the code will try to read the token from localStorage, jwt_decode it and set a user variable with the data that is in the token.
    • As tokens are not encrypted, just base64, their values can be changed in the dev console. A page that is "role: admin" only will be rendered if the permission is changed. The API will be responsible to check for permissions and reject the request if the token has been tampered.
    • Afaik, if it is stored in a variable it is a little less visible, it also gets wiped when reloading the page/browser.
    • When using a variable, to avoid refreshing the access token on every request, we can use the Context API, by creating a Component with the authenticated user context that will wrap the App/Router and then on every page that needs to be protected import and use this context and redirect if needed.
  4. When the access token is not valid anymore, because it has reached its expiry, or because it has been wiped, the API call will get rejected. Intercept this call then call the API refresh route to use the refresh token to generate a new access token.

    • I use axios with axios interceptor to intercept the failed request, call the refresh route, set the renewed access token, then retry the failed request. (needs to be a GET request to avoid CSRF errors apparently).
    • In addition (not in place of), a setTimeout can be used to automatically refresh the access token every X minutes to prevent letting it expire.
  5. To log out, remove the cookie (eventually blacklist) and wipe the context / localStorage.

Using axios, axios.defaults.withCredentials = true; makes sure that the cookie is sent with the requests and { headers: { 'Authorization': `Bearer ${access_token}` } } makes sure the access "bearer" token is sent with the request. These can either be set as defaults for every request or per request hence these 2 syntaxes.

Github example with Flask and React


以上是内存中的JWT访问令牌?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>