JWT 在浏览器中的存储策略

1. 前置

在讨论JWT的存储位置前,我们首先需要了解:

  • JWT主要用于验证数据完整性和来源可靠性,而非提供消息的机密性。由于JWT可能被解码,因此不建议直接存储敏感数据。
  • 在浏览器环境中,安全性相对较低,即使采用风险较低的方案,但是相比于后端等环境仍可能面临更高的潜在威胁。针对安全性需求较高的场景,推荐增加实施多因素认证(MFA)。

2. 存储环境对比

在浏览器环境中,常见的持久化存储位置包括:LocalStorage, SessionStorage, Cookie, 其中 Cookie 有一个特殊的 HttpOnly Cookie,以下是几个存储环境的特性对比:

特性 LocalStorage SessionStorage Cookie HttpOnly Cookie
数据持久性 持久存储,除非手动清除或用户清理数据 会话存储,关闭页面会话后数据被清除 可设置过期时间,默认为会话cookie 同Cookie
过期控制 可设置过期时间 可设置过期时间
存储容量 通常约5MB 通常约5MB 较小,通常4KB 同Cookie
数据共享 不随HTTP请求发送 不随HTTP请求发送 随HTTP请求发送 随HTTP请求发送,但不可通过JavaScript访问
访问限制 可通过JavaScript访问 可通过JavaScript访问 可通过JavaScript访问 不可通过JavaScript访问
自动发送 不自动发送 不自动发送 自动随请求发送 自动随请求发送
安全性 存在 XSS 攻击风险 存在 XSS 攻击风险 存在 XSS, CSRF 攻击风险 存在 CSRF 攻击风险;JS 无法访问,包括自己的
设置/获取方法 localStorage.setItem(), localStorage.getItem() sessionStorage.setItem(), sessionStorage.getItem() document.cookie document.cookie
适用场景 存储大量数据,非敏感数据 临时存储会话数据 用户认证,跟踪状态 安全的用户认证,减少XSS风险

3. 具体存储方案探讨

3.1. 前置说明

  1. 此章节关于 Cookie 的讨论均基于 SameSite=Lax 属性。
  2. HttpOnly Cookie 禁止 JS 获取 Cookie,所以 React, Vue 等框架也无法获取 JWT 的值。

*虽然 SameSite=Lax 大幅降低了 CSRF 风险,但是 SameSite-Lax 在预加载等场景仍可能存在 CSRF 风险。

3.2. 具体方案以及对比

方案一:使用 Access Token 和 Refresh Token,在 LocalStorage 存放短期的 Access Token,再使用 HttpOnly Cookie 中存放 Refresh Token。

  • 在安全性与兼容性中取平衡,
  • 优点:
    • LocalStorage 中存放的 Access Token 可以便捷的放到 Header authentication 中,兼容大部分主流框架;
    • 同时 Access Token 有效期较短,可以一定程度上降低泄露的风险;
    • Refresh Token 放在 HttpOnly Cookie 中可以有效降低 XSS 攻击风险;
    • 开发中可以分步开发,先实现简单的 Access Token 之后再实现 Refresh Token。
  • 缺点:
    • 前后端需要额外维护 Refresh Token;
    • Access Token 相对存在更高的 XSS 攻击风险;
    • LocalStorage 无法控制 token 在本地存储的时间。

方案二:使用 HttpOnly Cookie 存放 JWT。

  • 优点:
    • XSS 风险较低;
    • 可以有效控制 JWT 的存放时间。
  • 缺点:
    • SameSite=Lax 在预加载等场景仍可能存在 CSRF 风险;
    • 前端 JS 无法实现获取 JWT,所以无法将 JWT 存放到 Header authentication 中,所以与第三方前后端框架交互存在一定程度的兼容性;
    • 前期开发成本相对较高,需要手动实现相关 JWT 的解析、封装和管理。

4. 附言

综合而言,在浏览器环境中安全性相对较低,使用 JWT 的目的之一,就是为了简化认证流程,多应用单点登录,过分的依赖于 JWT 不会被窃取,强化 JWT 来源的识别,反而违背了 JWT 的设计。针对安全性需求较高的场景,推荐增加更多的安全校验如 IP 地址识别,设备识别等,以及实施多因素认证(MFA)。

5. 参考

  1. Token 放 localStorage?sessionStorage?還是 Cookie?| 是 Ray 不是 Array: https://israynotarray.com/information-security/20230516/18406287/
  2. authentication - Store Auth-Token in Cookie or Header? - Information Security Stack Exchange: https://security.stackexchange.com/questions/180357/store-auth-token-in-cookie-or-header
  3. authentication - Secure HttpOnly Cookie or Header field for auth token securing an API? - Information Security Stack Exchange: https://security.stackexchange.com/questions/119892/secure-httponly-cookie-or-header-field-for-auth-token-securing-an-api
  4. Using HTTPOnly Cookies to Strengthen User Authentication - Technology - Notarize | Notarize Blog: https://www.notarize.com/blog/using-httponly-cookies-to-strengthen-user-authentication


JWT 在浏览器中的存储策略
https://blog.cc01cc.cn/2024/10/30/storage-strateies-jwt-browser/
作者
零一/cc01cc(zeo)
发布于
2024年10月30日
许可协议