使

使用 JSON Web Token 保护你的 Node.js 应用程序

2025-06-07

使用 JSON Web Token 保护你的 Node.js 应用程序

转载自CodeWall
当你构建一个前后端分离的 Web 应用程序时,一种将其置于登录状态的方法是使用JSONWebToken。这个概念在 2010 年代初推出后迅速流行起来。在本文中,你将了解什么是 JSON Web Token (JWT),它是如何工作的,以及如何将它集成到你的 Node.js 应用程序中。让我们开始吧!

JSON Web Token 简介

官网上写道:“JSON Web Token 是一种开放的、行业标准的方法,用于在双方之间安全地表达声明”。这意味着,服务器可以确定客户端发送的信息(JSON 格式)是否未被修改,并且是否由该服务器有效签发。

代币包含什么?

JSON Web Token 由三部分组成:

  • 📃 Header:包含额外信息,例如令牌类型(JWT)以及所使用的签名算法(例如 SHA256)。标头 JSON 采用 Base64Url 编码。
  • 📦 Payload:包含双方想要共享的信息(或“声明”)。这可以包含任何你想要的内容,但共享敏感数据(例如密码)永远不是一个好主意,因为默认情况下,JWT 令牌无需共享密钥即可解码。JWT 的目标不是加密数据。我个人通常使用用户 ID、角色、签发日期和到期日期。除了标头 JSON 之外,Payload JSON 也使用 Base64Url 编码。
  • 🔏签名:签名包含编码的标头、编码的有效负载、秘密(只有您的服务器知道)并由标头中确定的算法签名。

如果散列算法是 SHA256,则签名将按如下方式创建:

HMACSHA256(
base64UrlEncode(header)
+ "."
+ base64UrlEncode(payload)
,secret)
Enter fullscreen mode Exit fullscreen mode

最后,所有三个部分都被连接起来,用“。”分隔:

<Header>.<Payload>.<Signature>
Enter fullscreen mode Exit fullscreen mode

下面是一个 JWT 示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1ZDM5YzI4MjdhZDgyMjBmMTJiMGZkMWIiLCJyb2xlIjoiYWRtaW4iLCJpYXQiOjE1NjUyNzE4NzUsImV4cCI6MTU2NjQ4MTQ3NX0.NmcvfTBmUw1cdEI1cNRHzq6q5W0HmPELoh8rd_7EFAc
Enter fullscreen mode Exit fullscreen mode

花点时间前往jwt.io并将令牌粘贴到那里。您将看到它包含的所有信息(签名除外)。

JWT 令牌如何工作?

需要注意的是,JWT 并非用于交换加密数据。它绝不能包含敏感信息,例如密码。JWT 的关键在于对令牌的验证。当您尝试验证已被篡改的令牌(例如用户 ID 被替换)时,该令牌将被拒绝。

为什么?因为内容不再与签名匹配。所以除了你之外的其他人无法创建有效的令牌,除非他们拿到了你用来哈希签名的密钥。

如果您的 JWT 密钥因某种原因被黑客入侵,您需要立即更改它。此后所有现有的令牌都将失效。这可能会让某些已登录的用户感到困扰,但您可以确保没有人能够为您的应用程序生成有效的令牌。

JWT 工作流程在服务器上是什么样的?

客户端与服务器之间的 JWT 工作流

现在我们对 JWT 有了一定的了解,让我们看一个例子来了解它如何与客户端-服务器交换一起工作。

  1. 第一步是客户端。客户端可以是 Web 前端应用、移动应用等等。基本上,任何试图与后端应用交互的程序(例如 REST API)都可以。客户端会将用户的登录凭据发送到服务器进行验证。

  2. 当服务器收到登录请求时,它首先会确保用户名/邮箱地址和密码与数据库中存储的信息匹配。如果凭据正确,则意味着服务器确认该用户的身份。

  3. 接下来,生成 JWT 令牌。在这里,用于识别用户的重要信息被传递到有效负载中。最好也包含签发日期和到期日期。这样,会话的有效期永远不会超过您指定的时间。一周似乎是一个不错的时间跨度。无论如何,用户每次使用后都应该退出应用程序,对吧?但这只会增加额外的安全性,避免出现僵尸登录用户。

  4. 然后,令牌将作为登录尝试的响应返回给客户端。当客户端收到令牌时,这意味着登录成功。令牌应该存储在客户端本地的某个位置。对于 Web 应用程序,这可以是 localStore;对于移动应用程序,这可以是设备变量中的某个位置。

  5. 为了与服务器进行所有后续通信,客户端会在每个请求中添加一个身份验证标头。如下所示:
    Authentication: Bearer

  6. 当对受保护资源的新请求到达服务器时,服务器首先会检查请求中是否包含身份验证标头。如果包含,服务器会尝试验证令牌是否有效。如果令牌无效(例如已被篡改、已过期等),则应立即拒绝该请求。

  7. 但是,如果令牌有效,则服务器可以安全地假定用户仍然是他所说的那个人,并且可以将请求的资源作为响应返回给客户端。

Node.js 应用程序中的 JWT

在本文中,我不会详细介绍 Node.js 中的 Web 服务器工作原理。但我将向您展示如何在 JavaScript 服务器环境中使用 JWT。

准备

为了使用 JWT,你可以使用这个便捷的jsonwebtoken库。安装方法如下:

npm install jsonwebtoken
Enter fullscreen mode Exit fullscreen mode

创建令牌

在您确定客户端是否提供了正确的登录凭据的代码中(可能就在您检查数据库之后),您可以创建 JSON Web Token:

const token = jwt.sign(<Your payload>, <Your JWT secret>, { expiresIn: <Expiration Time> })
Enter fullscreen mode Exit fullscreen mode

在真实的例子中,它可能看起来像这样:

const jwt = require('jsonwebtoken')
const token = jwt.sign({ _id: user._id, admin: true }, process.env.JWT_SECRET, { expiresIn: '1 week' })
Enter fullscreen mode Exit fullscreen mode

请注意两件事:

  • 如果您不熟悉dotenvprocess.env.JWT_SECRET则 JWT 密钥将存放于此。将令牌以明文形式存储在代码中绝不是一个好主意,因此最好使用诸如 dotenv [ https://www.npmjs.com/package/dotenv ] 之类的工具将其放置在不会上传到 Git 仓库的文件中。
  • expiredIn 属性可以是字符串形式的人类可读的时间指示:-*'4 天'-*'7 小时'-*'2 周'-*'6 个月'-* 等。

验证令牌

您的客户端应将身份验证标头设置为: Bearer: 。因此,您首先需要"Bearer: "从字符串中剥离该部分:

const token = req.header('Authorization').replace('Bearer ', '')
Enter fullscreen mode Exit fullscreen mode

(req.header('Authorization') 是 Express.js 读取授权标头的方式)

然后,您可以按如下方式验证提供的令牌:

const jwt = require('jsonwebtoken')
try{
    const payload = jwt.verify(token, process.env.JWT_SECRET) 
    console.log(payload._id)
} catch(error) {
    console.error(error.message)
}
Enter fullscreen mode Exit fullscreen mode

如果令牌有效,您将能够直接访问有效载荷变量中的所有有效载荷数据。如果令牌无效,JWT 库将抛出一个错误,您可以在 catch 中处理该错误。

概括

就是这样!如你所见,使用 JWT 并不复杂。最重要的一点——我再怎么强调也不为过——是 JWT 不会加密你的数据,因此请勿使用它来交换敏感信息。JSON
Web Token 是一项非常有效的技术,可以用来验证某人声称拥有的信息是否真实。
祝你编程愉快!

文章来源:https://dev.to/themarcba/secure-your-node-js-application-with-json-web-token-4d4e
PREV
使用 .some() 和 .every() 数组方法编写更简洁的 JavaScript 代码 它们如何工作?示例总结
NEXT
我的全栈 Web 开发人员资源简介全栈前端后端结束语