当前位置: 首页 > 知识库问答 >
问题:

为什么不将JWT访问令牌存储在内存中,并在cookie中刷新令牌?

吕德惠
2023-03-14

在处理基于浏览器的应用程序时,关于安全存储JWT令牌的主题已经提出了很多问题。大家一致认为,应该使用仅限http的安全cookie。然而,当涉及短期访问令牌和长期刷新令牌时,存储JWT令牌似乎存在许多变化。

我发现了以下变化:

1.仅将JWT访问令牌和刷新令牌存储在http安全cookie中

赞成的意见:

  • 无法从Javascript访问访问令牌和刷新令牌

欺骗:

  • 引入CSRF漏洞,因此也必须添加CSRF令牌

此处的首要答案建议添加CSRF令牌:https://stackoverflow.com/a/37396572/6735966

2.将JWT访问令牌存储在内存中,并仅在http安全cookie中刷新令牌

赞成的意见:

  • 无法从Javascript访问刷新令牌
  • 通过Javascript发送访问令牌,因此访问令牌不易受到CSRF的攻击
  • 刷新cookie只能用于获取新的访问令牌。使用正确的CORS设置,不可能通过恶意方的跨站点请求从响应中读取访问令牌。因此,这种方法似乎不受CSRF的影响

欺骗:

  • 访问令牌可以通过Javascript访问(但是访问令牌很快过期)

在这里推荐,但获得的票数比顶帖少得多:https://stackoverflow.com/a/63593954/6735966

3.将刷新令牌存储在内存中,JWT访问令牌存储在仅限超文本传输协议的安全cookie中

赞成的意见:

  • 无法从Javascript访问访问令牌
  • 刷新令牌通过Javascript发送,因此刷新令牌不容易受到CSRF的攻击

欺骗:

  • 可以从Javascript访问寿命更长的刷新令牌
  • 访问令牌易受CSRF攻击

下面的顶部答案中描述了类似的方法:https://stackoverflow.com/a/54378384/6735966

考虑到在内存中存储JWT访问令牌和仅在http中存储刷新令牌的利弊,安全cookie对我来说绝对是个好主意。然而,尽管在这个话题上有很多问题,但没有一个投票的答案甚至考虑到这种方法。因此,我的问题是:为什么不将JWT访问令牌存储在内存中,将刷新令牌存储在cookie中,而使用其他方法之一呢?

共有1个答案

罗鸿畴
2023-03-14

将cookie存储在内存中是可行的,但一个问题是如果您有同一客户机的多个实例。

另一种方法是像在ASP中那样做。NET核心,默认情况下,cookie在会话cookie中加密存储。但是,此cookie不能用于访问任何API,因为JavaScript无法访问它。此外,为了避免CSRF问题,您通常会html" target="_blank">添加常见的antiforgery令牌/cookie以防止CSRF攻击。

因此,最常用的方法是在ASP中存储令牌。NET核心位于会话cookie中。但同时,这会使cookie增长很多,因此当您觉得cookie的大小变大时,就开始考虑将其存储在内存或数据库/Redis存储中。

在。例如,通过使用SessionStore已经内置了对它的支持。下面的图片试图显示这是如何工作的,其中SessionKey存储在cookie中,然后令牌存储在内存/后端中。

是的,这就是它在ASP中的工作方式。NET内核,我相信您也可以在其他平台上找到类似的方法。

另一种选择是使用似乎越来越流行的BFF模式。

 类似资料:
  • 我正在尝试使用 GraphQL 使用 JWT 对用户进行身份验证。登录用户后,我会收到令牌作为 JSON 响应和存储刷新令牌的 httponly cookie。(服务器端使用的是销售核心) 从Saleor的文档和其他一些博客帖子中,我假设这个响应cookie现在应该存储在浏览器中,每当我需要刷新令牌时,cookie refreshToken将用于验证我的请求。然而,当我在开发工具中将选项卡切换到“

  • 我正在尝试从应用程序服务中获取Google的刷新令牌,但我不能。 日志说 2016-11-04T00:04:25 PID[500]收到的详细请求:获取https://noteappsvr.azurewebsites.net/.auth/login/google?access _ type = offline 2016-11-04t 00:04:25 PID[500]从https://account

  • 这是我的身份验证流程: 用户登录后收到两个令牌(具有过期时间的访问令牌和没有过期时间的刷新令牌) 对于每个用户,刷新令牌存储在数据库中名为refreshTokens的json列中(这是一个数组) 在客户端,访问令牌和刷新令牌都存储在本地存储器上 当需要验证用户时,如果访问令牌过期,将使用刷新令牌创建一个新的访问令牌,并将其发送回用户并保持用户登录 当用户注销时,数据库中存储的刷新令牌(在refre

  • 我使用带有Angular 9的Spring boot和无状态会话实现。应用程序正在成功执行登录和注册功能。字符串引导在每个登录请求上生成令牌(JWT)。登录后,当我尝试运行第二个选项卡的应用程序时,它再次要求我登录。为了克服这个问题,我将令牌保存在LocalStorage,然后在单击另一个选项卡时,angular代码能够从LocalStorage中选择令牌。但是经过一些研发,我知道应该使用HTTP

  • Stormpath 中有很多博客文章讨论了您应该如何使用 cookie 而不是 sessionStorage/localStorage 来存储您的 JWT: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage https://stormpath.com/blog/token-auth-sp

  • 我刚刚读了一篇文章 https://hasura . io/blog/best-of-practices-of-use-jwt-with-graph QL/ 总之,他们建议将JWT Access Token存储在内存中(例如在JavaScript中作为变量),并在HTTP-唯一Cookie中刷新Token。 他们说: 但是,通过通过刷新令牌间接地保持会话,我们防止了JWT令牌可能存在的直接CSRF