【问题标题】:Access Tokens, Refresh Tokens, And User Data访问令牌、刷新令牌和用户数据
【发布时间】:2022-11-17 12:15:02
【问题描述】:

我正在为我的应用程序使用 JWT 身份验证方案。我做了一些关于如何存储和使用访问和刷新令牌的研究,但我有几个问题我无法真正找到答案。对于应用程序,我在前端使用 React,在后端使用 .NET 6 Web API。

问题一:存储什么在哪里?
根据我所做的研究,出于安全原因,本地存储不是存储 jwt 令牌的好地方。因此,第二个最佳选择可能是 jwt 令牌的 HttpOnly cookie 和刷新令牌的本地存储。但是我确实读过一些文章,其中 jwt 令牌存储在本地存储中,而刷新令牌存储为 HttpOnly cookie。哪种方法更好,以及每种方法的优缺点。 P.S 我将轮换令牌,即一旦刷新旧的 jwt 令牌,将生成一个新的访问和刷新令牌。或者甚至存储在内存中比如 redux state

问题2:什么时候刷新 JWT Token?
jwt 令牌是否应该在其到期之前刷新,以便后端可以验证令牌,或者在令牌到期后刷新令牌是否可以(通过仅在刷新令牌时绕过验证,即刷新端点)。还应该通过设置计时器/间隔或等待请求失败来刷新吗?

问题三:访问用户数据和到期日期
我在 jwt 令牌中存储了一些用户数据,例如用户名和密码,这样我就可以在前端对它们进行访问。问题是当将 jwt 令牌设置为 HttpOnly cookie 时,由于 Javascript 无法访问令牌,我将无法访问用户数据和令牌的数据(例如 jti 和到期日期)。对于用户数据,我可以单独请求访问用户数据,例如用户名和电子邮件,但是对于 JWT 令牌的到期日期,我该如何获取呢?

如果有人遇到类似问题以及您如何解决这些问题,我将不胜感激这些问题的答案或任何反馈

【问题讨论】:

    标签: reactjs jwt .net-6.0 refresh-token


    【解决方案1】:

    将这些视为讨论而不是指南

    问题1:存储什么在哪里?

    • 在内存中存储访问令牌是一个不错的选择
    • 但是如果你有一个刷新令牌,并且你需要做一个静默登录,本地存储是唯一的选择
    • 但您始终可以在存储之前加密令牌

    问题二:什么时候刷新JWT Token?

    • 如果您等待令牌过期,然后使用刷新令牌进行刷新,则因令牌过期而失败的现有请求需要重新排队。
    • 如果您定期刷新令牌,如果现有令牌因刷新而失效,那么同样的问题会再次导致失败请求需要再次排队。 如果您使用的是 axios,则可以使用 axios-auth-refresh 之类的库,它将对失败的请求进行排队,然后使用新令牌重试。 您可以检查他们的源代码,或者如果处理失败的调用很重要,您可以创建自己的版本。

    问题三:访问用户数据和有效期

    • 访问令牌和 cookie 不应包含敏感信息 最好再次调用 api 来获取用户信息

    【讨论】:

    • 关于问题 3,token 到期日呢?
    • 我假设它的刷新令牌可能有几个月的有效期,在这种情况下,最好检查非常静默的登录,并在它到期之前更换它,通常最好存储由其他人提供的这种长期刷新令牌安全服务器上的身份验证提供商,并向用户传递自定义加密令牌以存储在他的设备上,并且可能会更频繁地更换它
    • 好主意,但我的意思是 JWT 令牌抱歉
    • 如果它是一个 JWT 访问令牌,它被设置为承载,找到 iat,在声明中发出,应该可以计算到期时间,也不是登录,静默登录 api 可以给出到期时间,一般访问令牌通常有较短的到期时间如果未加密,可以解码几个小时的 jwt 令牌 jwt.io
    【解决方案2】:

    问题一: 存储什么在哪里?

    首先,如果您无法安全地存储刷新令牌,则绝不建议使用它们。考虑构建一个传统的网络应用程序。

    其次,对于这些类型的令牌,始终建议使用会话存储而不是本地存储。

    但是,我理解这个问题,如果您的两个应用程序使用相同的域名,可以通过“Secure SameSite Cookies”来解决这个问题。 OWASP 有一些建议,看看“token side jacking”:https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html

    下面是一个简化版本(请阅读 OWASP 推荐并进行必要的调整):

    在身份验证过程中(Web API):

    1. 创建一个“用户上下文”,一个随机字符串
    2. 使用“用户上下文”设置访问令牌
    3. 使用“用户上下文”设置刷新令牌
    4. 使用强化 cookie 设置 http 响应标头(标记:HttpOnly + Secure + SameSite + cookie 前缀)。值:“用户上下文”

      您需要为 API 请求和刷新令牌流实施“用户上下文”验证;如果“cookie 用户上下文”与“令牌用户上下文”不匹配,则使用正确的 http 错误代码进行响应。

      这使得可以:

      • 在会话存储中存储访问令牌
      • 在本地存储中存储刷新令牌

      问题2: 什么时候刷新 JWT Token?

      jwt 令牌是否应该在其到期之前刷新,以便后端可以验证令牌,或者在令牌到期后刷新令牌是否可以(通过仅在刷新令牌时绕过验证,即刷新端点)。

      不,过期令牌的定义是它不再有效并且不能使用。

      还应该通过设置计时器/间隔或等待请求失败来刷新吗?

      等待请求失败。如果访问令牌和刷新令牌都已过期,则需要进行新的身份验证。

      问题三: 访问用户数据和到期日期

      不建议将敏感信息存储在访问令牌中。访问令牌对客户端应用程序应该是不透明的。使用一些标识符设置访问令牌,并创建一个返回用户信息的 /userinfo 端点。例如,创建一个具有两个操作的 authController:

      /token (used for authentication)

      /userinfo (used for retrieving information about the user)

    【讨论】:

      猜你喜欢
      • 2020-01-09
      • 2021-08-23
      • 2015-04-01
      • 2019-06-29
      • 2020-06-12
      • 1970-01-01
      • 2020-11-09
      • 2018-08-01
      • 2021-07-16
      相关资源
      最近更新 更多