如何在单页应用程序中保护 JWT

2025-05-27

如何在单页应用程序中保护 JWT

在 React 应用程序中安全地进行基于 JWT 的身份验证。

在本文中,我们将了解如何在单页应用程序中安全地存储 JWT 令牌以进行身份​​验证。

我们有哪些选项可以在浏览器中存储令牌?

  1. 本地存储
  2. 记忆
  3. 曲奇饼

本地存储中的 JWT

本地存储存储令牌安全吗?现在让我们看看,本地存储只能从客户端访问,因此,如果登录或注册 API 成功,您的 API 提供商会在 API 响应的 Authorization 标头中将 JWT 设置为持有令牌。在 React 中,我们将获取 JWT 并将其存储在本地存储中,如下所示

图片 1.png

图片 2.png

对于来自 React 应用程序的后续请求,将从本地存储中获取 JWT,并将其设置在 API 请求授权标头中,以维护用户会话

图片 3.png

本地存储中的值可以通过 javascript 访问,因此任何跨站点脚本都可以从本地存储获取 JWT 并获得您的帐户访问权限。

图片 4.png

因此,如果您正在使用本地存储来存储JWT,请更新您的身份验证架构,因为本地存储存储令牌并不安全。接下来,让我们转到内存

内存中的 JWT(React 状态)

React 的状态变量会在应用刷新或在新标签页中打开时被赋值默认值。如果默认值为 null,则在应用刷新或在新标签页中打开时,状态变量会被设置为 null。因此,当我们在状态变量中设置 JWT 时,它就会消失。这样一来,用户每次刷新或在新标签页中打开,或者关闭应用时都需要重新登录,用户体验很差。因此,我们不能将 JWT 存储在状态变量中。

在转到Cookie 中的 JWT之前,让我们先了解一下什么是 Cookie 及其主要属性

曲奇饼

Cookie 是浏览器中另一种可用的存储方式,它也有过期时间。Cookie 还具有一些有用的属性,可以防止跨站脚本 (XSS) 攻击。让我们详细了解一下它们是什么。

仅 Http

具有 HttpOnly 属性的 cookie 无法通过 Javascript 访问,因此我们无法获取以下 cookie



let cookie= document.cookie; 


Enter fullscreen mode Exit fullscreen mode

HttpOnly Cookie 只能由服务器端脚本设置和访问。如果使用SameSite=strict设置,此属性有助于防止跨站点脚本 (XSS) 攻击。

安全的

具有Secure属性的 Cookie仅通过 HTTPS 请求发送到服务器,而不会在 HTTP 请求中发送。Secure Cookie 在请求和响应中经过加密,因此使用带有HttpOnlySameSite=strict 的Secure 属性可以防止中间人攻击。

同一站点

SameSite=strict的 Cookie表明该 Cookie 仅适用于同源请求,不适用于跨站请求。现在让我们看看如何使用 Cookie 存储 JWT。

Cookie 中的 JWT

可以从服务器端也可以在客户端设置 cookie,首先我们可以看到如何在 React 中以及如何使用浏览器控制台从 cookie 设置和获取 JWT。

服务器在授权响应标头中将 JWT 设置为 Bearer 令牌,在客户端,脚本可以访问标头中存在的令牌,我们从响应标头中获取令牌并在 cookie 中设置,如下所示

图片5.png

图片6.png

该 cookie 默认设置为当前域,有效期设置为 2021 年 1 月 1 日。有效期取决于令牌的有效性,因此一旦达到有效期,令牌将从浏览器 cookie 中删除。

图片7.png

每次客户端发出请求时,都需要将 Cookie 作为 Bearer Token 添加到 API 请求头中。因此,我们可以使用document.cookie属性从 Cookie 中获取它,如下所示

图片8.png

document.cookie 将返回域中存在的所有 cookie,因此我们可以使用react-cookie包来获取特定的 cookie,如下所示

图片9.png

可以看到,Token 是通过脚本设置和获取的,因此我们可以得出结论,在 React 中处理 JWT 会导致 XSS(跨站脚本)攻击,就像我们之前在使用本地存储时遇到的那样。不过,我们之前看到了两个属性HttpOnlySecure,设置这两个属性可以避免这些攻击。但是 JavaScript 无法访问HttpOnly属性,只有服务器端脚本才能访问HttpOnly属性。让我们看看如何从服务器端设置 JWT。

如前面的例子,我们看到 JWT 在授权标头中被设置为 Bearer 令牌,但是在服务器端处理 cookie,我们需要在Set-Cookie标头中设置 cookie,而不需要将令牌类型提及为Bearer ,我们可以在Set-Cookie中直接设置 JWT

在这里,我使用 Express.js 在服务器的 cookie 中设置 JWT,并且我们将secureHttpOnly设置为true,以限制 cookie 中 JWT 的 javascript 访问,如下所示

图片 10.png

API 响应Set-Cookie标头中的令牌将保存到浏览器 cookie 中,如下图所示

图片 11.png

图片 12.png

存储在 cookie 中的 JWT 将自动附加到每个 API 请求标头中,如下图所示

图片 13.png

图片 14.png

但请记住,只有当 React 应用程序和 BackEnd 服务器托管在同一域中时,此方法才有效。

现在您的应用程序已免受跨站点脚本 (XSS) 攻击。

想要了解更多?欢迎在Twitter上与我们交流:)

你可以给我买杯咖啡来支持我 ☕

电子书

使用 ChatGPT 调试 ReactJS 问题:50 个基本技巧和示例

ReactJS 优化技术和开发资源

文章来源:https://dev.to/nilanth/how-to-secure-jwt-in-a-single-page-application-cko
PREV
企业应用程序的 React 架构
NEXT
调试——你做错了。10 种技巧帮你找到代码中的 bug