具有无状态服务器且无服务器端呈现的 cookie 中的 JWT 身份验证

Posted

技术标签:

【中文标题】具有无状态服务器且无服务器端呈现的 cookie 中的 JWT 身份验证【英文标题】:JWT auth in cookies with stateless server and no server side rendering 【发布时间】:2019-02-21 08:03:09 【问题描述】:

我正在尝试在 cookie 中实现 jwt 以在单页面应用程序反应前端进行身份验证,该前端与运行 express 的各种节点微服务通信。

我这样做是因为将 jwt 存储在 sessionStorage 中会使应用容易受到 XSS 的攻击。

但是,通过使用 cookie,api 现在容易受到 csrf 攻击。

传统上,通过创建一个 csrf 令牌,将其存储在服务器会话中,然后将其呈现在隐藏的表单字段中来缓解 csrf 攻击。 然后,在提交表单时,会根据服务器会话值检查 csrf 令牌的值以检查它们是否匹配。

我不能将这种方法用作: - 服务器是无状态的 - 没有服务器端渲染。

所以我对应该采用哪种 csrf 方法感到困惑。 我已经阅读过双重提交方法,您在每个 ajax 请求上提交一个 csrf 令牌,并将相同的值存储在 cookie 中,然后服务器检查两者是否匹配。

但是,由于没有服务器端渲染,我无法将初始 csrf 令牌放入 html

在没有服务器端渲染的无状态架构中,在具有 csrf 保护的 cookie 中实现 jwt 的最佳实践是什么?

【问题讨论】:

你是如何设置cookies的?大概您的一个微服务具有允许用户登录的身份验证端点? 使用 auth0,用户在他们网站上托管的登录页面上登录,有一个回调 url 他们被重定向到 url 参数中的令牌,目前存储在 localstorage 中。我不确定如何让它与 cookie 一起使用,我考虑使用令牌向服务器端点发布请求,然后返回 httponly cookie,但这对我来说似乎有点不安全。 【参考方案1】:

不要将 JWT 令牌存储在 cookie 中

CSRF 攻击是可能的,因为浏览器会发送带有 HTTP 请求的 cookie,即使它们是由运行在 3rd 方站点上的脚本发起的。因此evilsite.com 可能会向您的网络服务 发送DELETE http://yoursite.com/items/1 请求。此端点要求您登录,但因为浏览器将发送为 yoursite.com 存储的任何 cookie,如果身份验证是基于 cookie 的,那么 evilsite.com 可以捎带您的身份验证方法并调用您的用户不打算的身份验证方法代表他们打电话。

但是,身份验证不必基于 cookie。如果您正在创建客户端呈现的 javascript 应用程序,那么将身份验证令牌作为 HTTP 标头而不是在 cookie 中发送很简单。如果您这样做,那么evilsite.com 就不可能使用您的令牌(他们只能使用存储在 cookie 中的令牌),而且您一开始就不会遇到问题。

【讨论】:

所以您是说不要将 jwt 存储在 cookie 中,而是存储在本地存储中。那么它不会容易受到 XSS 的攻击吗?只是为了澄清一下,目前我在每个请求的标头中发送 jwt,但我必须将 jwt 存储在某个地方,目前在本地存储中,这很容易受到 XSS 的攻击,这就是为什么我正在寻找基于 cookie 的解决方案。跨度> 我相信只有在服务器设置的仅 HTTP cookie 的情况下,cookie 才能防止 XSS 攻击。在您的情况下,客户端已经可以访问令牌(通过 URL),因此您没有该选项。您只需要格外小心,不要让任何恶意脚本在您的网站上执行。见:security.stackexchange.com/questions/168605/… @MrF 仅供参考:如果攻击者在 XSS 中成功,他已经可以绕过你添加的每一个 CSRF 保护。我宁愿使用localStorage,防止CSRF,只担心XSS:这是一个小得多的攻击面。

以上是关于具有无状态服务器且无服务器端呈现的 cookie 中的 JWT 身份验证的主要内容,如果未能解决你的问题,请参考以下文章

Session与Cookie

无状态服务器如何工作?

HTTPHTTPS

cookie是啥?

COOKIE

详解Session和cookie