如果用于身份验证的 JWT 令牌保存在 HTTP-Only cookie 中,您如何从 cookie 中读取它以便我可以将其包含在请求标头中?

Posted

技术标签:

【中文标题】如果用于身份验证的 JWT 令牌保存在 HTTP-Only cookie 中,您如何从 cookie 中读取它以便我可以将其包含在请求标头中?【英文标题】:If the JWT token for auth is saved in the HTTP-Only cookie, how do you read it from the cookie so that I can include it in request header? 【发布时间】:2020-08-01 18:20:41 【问题描述】:

我正在使用 JWT 为用户身份验证构建一个 Node Web 应用程序。

当用户提交正确的 id 和密码时,我的服务器通过“Set-Cookie”在 HTTP-Only cookie 中发送 JWT,但我被困在如何访问存储在 cookie 中的 JWT 以便我可以在发出授权 API 请求时将其包含在 Authorization 标头中。

当向服务器发送 API 请求时,如何从客户端访问 HTTP-Only cookie 以包含它?

或者,通过让服务器在响应正文中发送 JWT,根本不使用 cookie 是否安全?所以我通过将 JWT 放在客户端变量中来使用它?这样,我相信该变量只有在用户关闭浏览器之前才有效。

我已经寻找了很多资源,但无法为我所困扰的这个问题找到明确的答案。

【问题讨论】:

忘了提到我没有使用任何客户端框架,例如 React 或 Vue。只是客户端的纯 javascript 【参考方案1】:

虽然有很多方法可以解决这个问题,但我会建议客户端在每个请求上发送两次 JWT 的方法:在 HttpOnly cookie 中,以及在 Authentication: 标头中。


让我们来看看每个解决了什么安全问题:

HttpOnly Cookie

来自the Mozilla documentation:

为帮助缓解跨站脚本 (XSS) 攻击,JavaScript 的 Document.cookie API 无法访问 HttpOnly cookie;它们只发送到服务器。

这是为了减轻跨站脚本风险;假设您的网站有一个 XSS 漏洞——例如,我可以将 <script>some_code..</script> 放入评论中,任何查看我评论的用户都会在他们的浏览器中运行我的代码。是的,攻击者的代码在受害者登录的浏览器中运行,但是由于HttpOnly标志,它无法提取会话cookie并将其发送给攻击者。

身份验证标头

cookie 身份验证的问题是浏览器会自动将它们附加到对 cookie 所属域的任何请求,这允许cross-site request forgery 攻击。为防止这种情况,通常的方法是通过 cookie 以外的方法将会话令牌(在您的情况下为 JWT)发送到客户端,即在不同的标头中,或者在隐藏的 html 字段中。

如果客户端能够在他们的下一个请求中将 JWT 令牌回显给您,这意味着他们能够读取之前的响应,并且不是进行盲注 CSRF 攻击的攻击者。


总体建议

将两者结合起来!

这两种方法有不同的用途:HttpOnly cookie 可防止 XSS 攻击,而 Authentication 标头可防止 CSRF 攻击。

有很多组合它们的方法,但它们都归结为将 JWT 放入某种身份验证标头中,并将 sessionID 放入 cookie 中,并让服务器检查它们是否属于同一个会话。重要提示:请记住,在您的站点上实现 XSS 的攻击者将能够读取 JWT,因此要使 cookie 发挥作用,cookie 应该是一个不包含在 JWT 中的单独值。 (即如果攻击者可以通过查看 JWT 找出正确的 cookie 值,那么 cookie 没有提供任何安全性。

【讨论】:

Samesite cookie属性可用于防止CSRF攻击developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/…

以上是关于如果用于身份验证的 JWT 令牌保存在 HTTP-Only cookie 中,您如何从 cookie 中读取它以便我可以将其包含在请求标头中?的主要内容,如果未能解决你的问题,请参考以下文章

用于反应前端的基于令牌的身份验证

我是不是正确理解用于身份验证的访问和刷新令牌技术?

使用 JWT 进行身份验证的最佳实践

用于跨域身份验证的 JWT 令牌

使用 JwT 令牌身份验证对 HTTP Rest API 的 Python 发布请求会生成重复的帖子

JWT 验证了在另一个浏览器中使用的偶数令牌