首页 > 解决方案 > 在客户端存储用户数据(用户 ID、用户名、JWT 令牌)的最佳选择是什么?

问题描述

我目前正在使用 localStorage 来存储用户信息,以及成功认证后的 JWT 令牌。这似乎不太安全,主要是因为可以轻松编辑和更改数据。

我需要用户 ID 来向服务器 REST API 发出请求。在客户端存储用户敏感数据的最佳解决方案是什么?我应该在登录后将数据存储在全局状态吗?

标签: javascriptjwtlocal-storage

解决方案


没有最好的选择,只有不同的取舍。

我目前正在使用 localStorage 来存储用户信息,以及成功认证后的 JWT 令牌。这似乎不太安全,主要是因为可以轻松编辑和更改数据。

这里有两个不同的东西:用户数据和令牌。

对于用户数据,我不建议将它们存储在本地存储中,因为任何人都可以轻松读取或修改它们。一些替代方法可能是使用Session storage,或者只是将它们保存在内存中并在需要时重新获取它们。你也可以加密它们。

关于 JWT 令牌本身,如果生成正确,至少应该对其进行签名(规范允许对令牌进行加密、签名或两者兼而有之)。在这种情况下,服务器将能够检测到令牌是否被更改,所以这不是问题。问题是,如果给定用户的令牌被盗,窃贼将能够以该用户身份登录,并且可能永远登录。

所以你需要做的是将攻击面限制到最大。它通常是安全性、可维护性和用户体验之间的权衡。以下是需要考虑的几点:

  • 创建令牌时可以设置到期时间。将其设置为相对较低的值(例如 15 分钟),以便在令牌被盗的情况下,至少攻击者可以获得更短的时间来执行任何恶意操作
  • 如果它必须存储在客户端,例如,因为您正在开发一个 SPA,该 SPA 通过调用 auth API 客户端来处理 javascript 中的身份验证,您将更容易受到XSS 攻击。在这种情况下,LocalStorage 实际上并不比其他任何选择更糟糕,而且它是一种方便的选择。内容安全策略 (CSP)以及始终转义用户输入有助于降低 XSS 的脆弱性。
  • 如评论中所指出的,如果可能,使用仅限 http 的 cookie 是一个不错的选择。令牌将由浏览器自动发送到服务器,并且对您的客户端代码不可见。然而,http-only cookie 通常更容易受到CSRF 攻击

推荐阅读