JWT应该存储在localStorage还是cookie?

时间:2016-01-15 18:38:24

标签: security cookies local-storage jwt restful-authentication

为了使用JWT保护REST API,根据一些材料(如guide和此question),JWT可以存储在 localStorage 缓存即可。根据我的理解:

  • localStorage 受XSS约束,一般不建议在其中存储任何敏感信息。
  • 使用 Cookie ,我们可以应用标记" httpOnly"这减轻了XSS的风险。但是,如果我们要在后端从Cookies读取JWT,那么我们将接受CSRF。

基于上述前提 - 最好将JWT存储在Cookies中。在每次向服务器发出请求时,将从Cookie中读取JWT并使用承载方案添加到授权标头中。然后,服务器可以验证请求标头中的JWT(而不是从cookie中读取它)。

我的理解是否正确?如果是这样,上述方法是否有任何安全问题?或者实际上我们可以在第一时间使用localStorage逃脱?

4 个答案:

答案 0 :(得分:27)

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

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

无论是将JWT存储在localStorage中还是将XSRF令牌存储在非http-only cookie中,都可以通过XSS轻松获取。甚至你的HttpOnly cookie中的JWT也可以通过高级XSS攻击来抓取。

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

答案 1 :(得分: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/

答案 2 :(得分:9)

及时post from Stormpath已经详细阐述了我的观点并回答了我的问题。

TL; DR

将JWT存储在cookie中,然后在我提到的每个请求上通过授权标头中的JWT,或者如文章所示,依靠后端来防止CSRF(例如使用xsrfToken of Angular)。

答案 3 :(得分:0)

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

这仍然是a draft,截至2019年是not fully supported by all current browsers,但是根据您数据的敏感度和/或您对用户使用的浏览器的控制,这可能是一个可行的选择。使用SameSite=lax设置指令将允许“使用'safe'... HTTP方法的顶级导航。”