如何在单页应用程序中保护 JWT
在 React 应用程序中安全地进行基于 JWT 的身份验证。
在本文中,我们将了解如何在单页应用程序中安全地存储 JWT 令牌以进行身份验证。
我们有哪些选项可以在浏览器中存储令牌?
- 本地存储
- 记忆
- 曲奇饼
本地存储中的 JWT
本地存储存储令牌安全吗?现在让我们看看,本地存储只能从客户端访问,因此,如果登录或注册 API 成功,您的 API 提供商会在 API 响应的 Authorization 标头中将 JWT 设置为持有令牌。在 React 中,我们将获取 JWT 并将其存储在本地存储中,如下所示
对于来自 React 应用程序的后续请求,将从本地存储中获取 JWT,并将其设置在 API 请求授权标头中,以维护用户会话
本地存储中的值可以通过 javascript 访问,因此任何跨站点脚本都可以从本地存储获取 JWT 并获得您的帐户访问权限。
因此,如果您正在使用本地存储来存储JWT,请更新您的身份验证架构,因为本地存储存储令牌并不安全。接下来,让我们转到内存
内存中的 JWT(React 状态)
React 的状态变量会在应用刷新或在新标签页中打开时被赋值默认值。如果默认值为 null,则在应用刷新或在新标签页中打开时,状态变量会被设置为 null。因此,当我们在状态变量中设置 JWT 时,它就会消失。这样一来,用户每次刷新或在新标签页中打开,或者关闭应用时都需要重新登录,用户体验很差。因此,我们不能将 JWT 存储在状态变量中。
在转到Cookie 中的 JWT之前,让我们先了解一下什么是 Cookie 及其主要属性
曲奇饼
Cookie 是浏览器中另一种可用的存储方式,它也有过期时间。Cookie 还具有一些有用的属性,可以防止跨站脚本 (XSS) 攻击。让我们详细了解一下它们是什么。
仅 Http
具有 HttpOnly 属性的 cookie 无法通过 Javascript 访问,因此我们无法获取以下 cookie
let cookie= document.cookie;
HttpOnly Cookie 只能由服务器端脚本设置和访问。如果使用SameSite=strict设置,此属性有助于防止跨站点脚本 (XSS) 攻击。
安全的
具有Secure属性的 Cookie仅通过 HTTPS 请求发送到服务器,而不会在 HTTP 请求中发送。Secure Cookie 在请求和响应中均经过加密,因此使用带有HttpOnly和SameSite=strict 的Secure 属性可以防止中间人攻击。
同一站点
SameSite=strict的 Cookie表明该 Cookie 仅适用于同源请求,不适用于跨站请求。现在让我们看看如何使用 Cookie 存储 JWT。
Cookie 中的 JWT
可以从服务器端也可以在客户端设置 cookie,首先我们可以看到如何在 React 中以及如何使用浏览器控制台从 cookie 设置和获取 JWT。
服务器在授权响应标头中将 JWT 设置为 Bearer 令牌,在客户端,脚本可以访问标头中存在的令牌,我们从响应标头中获取令牌并在 cookie 中设置,如下所示
该 cookie 默认设置为当前域,有效期设置为 2021 年 1 月 1 日。有效期取决于令牌的有效性,因此一旦达到有效期,令牌将从浏览器 cookie 中删除。
每次客户端发出请求时,都需要将 Cookie 作为 Bearer Token 添加到 API 请求头中。因此,我们可以使用document.cookie属性从 Cookie 中获取它,如下所示
document.cookie 将返回域中存在的所有 cookie,因此我们可以使用react-cookie包来获取特定的 cookie,如下所示
可以看到,Token 是通过脚本设置和获取的,因此我们可以得出结论,在 React 中处理 JWT 会导致 XSS(跨站脚本)攻击,就像我们之前在使用本地存储时遇到的那样。不过,我们之前看到了两个属性HttpOnly和Secure,设置这两个属性可以避免这些攻击。但是 JavaScript 无法访问HttpOnly属性,只有服务器端脚本才能访问HttpOnly属性。让我们看看如何从服务器端设置 JWT。
如前面的例子,我们看到 JWT 在授权标头中被设置为 Bearer 令牌,但是在服务器端处理 cookie,我们需要在Set-Cookie标头中设置 cookie,而不需要将令牌类型提及为Bearer ,我们可以在Set-Cookie中直接设置 JWT 。
在这里,我使用 Express.js 在服务器的 cookie 中设置 JWT,并且我们将secure和HttpOnly设置为true,以限制 cookie 中 JWT 的 javascript 访问,如下所示
API 响应Set-Cookie标头中的令牌将保存到浏览器 cookie 中,如下图所示
存储在 cookie 中的 JWT 将自动附加到每个 API 请求标头中,如下图所示
但请记住,只有当 React 应用程序和 BackEnd 服务器托管在同一域中时,此方法才有效。
现在您的应用程序已免受跨站点脚本 (XSS) 攻击。
想要了解更多?欢迎在Twitter上与我们交流:)
你可以给我买杯咖啡来支持我 ☕
电子书
使用 ChatGPT 调试 ReactJS 问题:50 个基本技巧和示例
文章来源:https://dev.to/nilanth/how-to-secure-jwt-in-a-single-page-application-cko