JWT应该存储在localStorage还是cookie中?[重复]


99

为了使用JWT保护REST API,根据某些资料(如本指南和此问题),JWT可以存储在任一localStorage中Cookies中。根据我的理解:

  • localStorage受XSS限制,通常不建议在其中存储任何敏感信息。
  • Cookie,我们可以应用标志“ httpOnly”,以减轻XSS的风险。但是,如果我们要从后端的Cookies中读取JWT,则需要接受CSRF。

因此,基于以上前提,最好将JWT存储在Cookies中。在对服务器的每个请求中,都将使用Cookie方案从Cookie中读取JWT并将其添加到Authorization标头中。然后,服务器可以验证请求标头中的JWT(与从Cookie中读取JWT相反)。

我的理解正确吗?如果是这样,上述方法是否涉及安全性?还是实际上我们可以首先使用localStorage逃脱?



@ lrn2prgrm不应该同时使用(无状态)JWT(有状态)会话语义。
ozanmuyes

Answers:


56

我喜欢@ pkid169所说的文章中提到的XSRF Double Submit Cookies方法,但是有一件事情没有告诉您。您仍然没有受到XSS的保护,因为攻击者可以执行的操作是注入脚本,该脚本读取CSRF cookie(不是HttpOnly),然后使用此CSRF令牌向您的API端点之一发出请求,并自动发送JWT cookie。

因此,实际上您仍然容易受到XSS的攻击,只是攻击者无法窃取您的JWT令牌供以后使用,但攻击者仍然可以使用XSS代表您的用户发出请求。

无论是将JWT存储在localStorage中,还是将XSRF令牌存储在非仅HTTP的cookie中,XSS都可以轻松地将两者捕获。甚至您的HttpOnly cookie中的JWT都可以通过高级XSS攻击来抢夺。

因此,除了使用Double Submit Cookies方法外,您还必须始终遵循针对XSS的最佳做法,包括转义内容。这意味着删除所有可能导致浏览器执行您不​​希望执行的操作的可执行代码。通常,这意味着删除// <![CDATA [标签和HTML属性,这些属性会导致对JavaScript进行评估。


11
您能否阐明如何获取HttpOnly cookie中的JWT?如果XSRF令牌被XSS破坏,则XSRF可以使用它,但是它真的可以自己被抢走吗?
JacekGorgoń17年

1
我知道这是一篇旧文章,但是我想提一些问题...这是否意味着精心制作的脚本可以读取localStorage和cookie?如果是这样,可以安全地假设无论我们将JWT存储在浏览器中的哪个位置,JWT都可能被盗?然后,我觉得仅依靠JWT很有风险。
弘树

2
“即使您的HttpOnly cookie中的JWT也可以通过高级XSS攻击来抢夺。” 是假的。编辑原始帖子以更正此问题。
java-addict301

“即使通过高级XSS攻击也可以捕获HttpOnly cookie中的JWT”,我可以想象有人通过将cookie发送到自己的服务器来捕获cookie。为此,他可以使用具有适当值的凭据标志的访存。这里的主要问题是CORS保护,但我认为在某些情况下是可能的。
bartnikiewi.cz

“插入读取您的CSRF cookie(不是HttpOnly)的脚本”Html.AntiForgeryToken()在ASP.NET MVC中,默认实现使用CSRF令牌的HttpOnly cookie。我认为您仍然容易受到某些XSS的影响,但我认为这值得一提。
Lovethenakedgun

21

来自Stormpath的及时发布已经阐明了我的观点并回答了我的问题。

TL; DR

将JWT存储在cookie中,然后像我提到的那样在每个请求上将JWT传递到Authorization标头中,或者如文章所述,依靠后端来防止CSRF(例如,xsrfToken在Angular中使用)。


1
您好,我不确定这是否正确,但是在为控制器实现CrossOrigin时使用cookie存储jwt是否有一些特殊的缺点,在这种情况下,我的服务器应用程序位于其他位置,因此我们称之为api在我们位于其他城市的客户端应用中来自它?难道为什么许多Web服务提供商都不使用Cookie?
valik '18

CrossOrigin并不意味着实际位置。它指的是来自其他域的请求。在.net core中,当您决定使用CORS时,您将指定要允许的域。您将允许使用哪些标题,等等
布赖恩·艾伦·韦斯特

11
  • 不要将令牌存储在LocalStorage或SessionStorage中,因为可以从javascript中读取此类令牌,​​因此容易受到XSS攻击。
  • 不要将令牌存储在Cookie中。Cookie(带有HttpOnly标志)是一个更好的选择-易于XSS,但容易受到CSRF攻击

相反,您可以在登录时交付两个令牌:访问令牌和刷新令牌。访问令牌应存储在Javascript内存中,刷新令牌应存储在HttpOnly Cookie中。刷新令牌仅用于创建新的访问令牌,仅此而已。

当用户打开新选项卡或在站点刷新时,您需要基于存储在Cookie中的刷新令牌执行请求以创建新的访问令牌。

我也强烈建议您阅读以下文章:https : //hasura.io/blog/best-practices-of-using-jwt-with-graphql/


5
为什么仅将刷新令牌视为访问令牌会增加复杂性?这是如何的做法更安全给我记住我的访问令牌securesamesite: stricthttp-only
迷人的机器人

这不是更安全
克里斯·霍克斯

2

为了帮助防止利用现有Cookie的CSRF攻击,您可以使用SameSite指令设置Cookie 。将其设置为laxstrict

这仍然是草案,截至2019年,当前所有的浏览器均未完全支持它,但是取决于数据的敏感性和/或您对用户使用的浏览器的控制,这可能是一个可行的选择。将指令设置为SameSite=lax会允许“使用'safe'... HTTP方法的顶级导航”。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.