我正在开发一个 Web 应用程序,我想使用基于令牌的身份验证,但在服务器端实现该功能后,我一直试图找出在客户端存储 JWT 的最佳方法。
我发现自己在安全性和“易于开发”之间进行一系列权衡。
众所周知,httpOnly cookie 是安全存储令牌并保护其免受 XSS 攻击的最佳方式,但是如果 JWT 存储在 cookie 中,客户端将如何访问它的值呢? JavaScript 不允许读取 httpOnly cookie。客户端如何处理路由验证?浏览器不会像 cookie 那样自动设置
Authorization
标头。
众所周知,本地存储在 CSRF 攻击方面是安全的,但在 XSS 攻击方面则不然。尽量避免在本地存储中存储敏感数据是常识。
我详细阐述了以下解决方案:
我可以将 JWT 存储在 httpOnly cookie 中。服务器不会接受没有
Authorization
标头的请求,因此解决方案是在服务器上放置一个中间件,该中间件会从 cookie 中读取令牌,设置 Authorization
标头,最后将请求传递给下一个处理程序。
优点:
https://example.com/protected
时,他们的请求将被授权绕过浏览器,而不自动设置 Authorization
标头(服务器会这样做)。缺点:
如果你们能给我指出正确的方向并提出建议,告诉我我是否使事情过于复杂以及是否有更好的方法,我将不胜感激。
Lokal Storage 无法使用的原因与您提到的 XXS 攻击完全相同。 安全存储是仅 http 的 cookie 存储或会话存储。 如果可能的话,我个人更喜欢前者,但两者都被认为是有效的选择。 Auth0 使用后者。
将 JWT 从 cookie 移动到 header 的中间件是一个有效的设计。它允许其他客户端(例如应用程序)(无浏览器=无 cookie)使用 JWT 的标头传输。
在使用 httpOnly cookie 时,根据用户权限向客户端 UX 发出警报的安全方法是,同时在登录的响应正文中或在获取用户信息的特定请求中将 JWT 作为(未编码的)常规 json 发送。 有人可能会问,这如何安全?嗯,客户端代码从来都不是安全的,这种设计表明了这一点,并消除了任何虚假的安全感。无论您从签名的 JWT 还是常规的 json 响应中获取用户“权限”,它仍然可以在客户端中更改,并且只能用于 UX。就像隐藏一个供管理员使用的按钮一样,因为普通用户按下该按钮只会返回 403,所以我们使用范围使其看起来更好,隐藏该按钮。