javascript - 在客户端存储用户数据(用户 ID、用户名、JWT 令牌)的最佳选择是什么?
问题描述
我目前正在使用 localStorage 来存储用户信息,以及成功认证后的 JWT 令牌。这似乎不太安全,主要是因为可以轻松编辑和更改数据。
我需要用户 ID 来向服务器 REST API 发出请求。在客户端存储用户敏感数据的最佳解决方案是什么?我应该在登录后将数据存储在全局状态吗?
解决方案
没有最好的选择,只有不同的取舍。
我目前正在使用 localStorage 来存储用户信息,以及成功认证后的 JWT 令牌。这似乎不太安全,主要是因为可以轻松编辑和更改数据。
这里有两个不同的东西:用户数据和令牌。
对于用户数据,我不建议将它们存储在本地存储中,因为任何人都可以轻松读取或修改它们。一些替代方法可能是使用Session storage,或者只是将它们保存在内存中并在需要时重新获取它们。你也可以加密它们。
关于 JWT 令牌本身,如果生成正确,至少应该对其进行签名(规范允许对令牌进行加密、签名或两者兼而有之)。在这种情况下,服务器将能够检测到令牌是否被更改,所以这不是问题。问题是,如果给定用户的令牌被盗,窃贼将能够以该用户身份登录,并且可能永远登录。
所以你需要做的是将攻击面限制到最大。它通常是安全性、可维护性和用户体验之间的权衡。以下是需要考虑的几点:
- 创建令牌时可以设置到期时间。将其设置为相对较低的值(例如 15 分钟),以便在令牌被盗的情况下,至少攻击者可以获得更短的时间来执行任何恶意操作
- 如果它必须存储在客户端,例如,因为您正在开发一个 SPA,该 SPA 通过调用 auth API 客户端来处理 javascript 中的身份验证,您将更容易受到XSS 攻击。在这种情况下,LocalStorage 实际上并不比其他任何选择更糟糕,而且它是一种方便的选择。内容安全策略 (CSP)以及始终转义用户输入有助于降低 XSS 的脆弱性。
- 如评论中所指出的,如果可能,使用仅限 http 的 cookie 是一个不错的选择。令牌将由浏览器自动发送到服务器,并且对您的客户端代码不可见。然而,http-only cookie 通常更容易受到CSRF 攻击。
推荐阅读
- ruby-on-rails - Cancancan - 在 Rails Admin 中访问被拒绝
- arrays - 从 indexedDB 在 Vue 中返回未定义的数组
- vb.net - 在 vb.net PowerPoint 加载项中单击用户控件上的按钮后,如何从按钮上移除键盘焦点?
- makefile - 如何从 Makefile 运行 nyc merge?
- c# - 强制某些代码始终在同一个线程上运行
- arrays - 使用另一个一维数组过滤一个二维数组
- php - 检查集合中的组合是否存在于表中
- flask - 将 2 个具有 1:1 关系的模型组合成一个没有嵌套的方案?
- javascript - 编辑操作中具有不同值和不同选定值的mat-select中的自动选择问题
- javascript - 固定位置不会在其他浏览器中保持固定