如何在 Express.js 中使用 JSON 网络令牌 (JWT)

介绍

JSON Web Tokens (JWTs) 支持授权和信息交换。

一个常见的用例是允许客户端在登录后保留他们的会话信息。通过在本地存储会话信息并在发出请求时将其传递给服务器进行身份验证,服务器可以相信客户端是注册用户。

在本文中,您将了解 JWT 在使用 Node.js 和 vanilla JavaScript 的服务器-客户端关系中的应用。

先决条件

要跟随本文,您需要在您的机器上安装以下内容:

第 1 步 – 生成令牌

jsonwebtoken 是 JSON Web 令牌的实现。

您可以通过在终端中运行以下命令将其添加到您的 JavaScript 项目中:

  • npm install jsonwebtoken

并将其导入到您的文件中,如下所示:

const jwt = require('jsonwebtoken');

要签署令牌,您需要有 3 条信息:

  1. 令牌秘密
  2. 要在令牌中散列的数据
  3. 令牌过期时间

令牌密钥是用于加密和解密数据长随机数序列。

要生成这个秘密,一种选择是使用 Node.js 的内置crypto库,如下所示:

> require('crypto').randomBytes(64).toString('hex')
// '09f26e402586e2faa8da4c98a35f1b20d6b033c6097befa8be3486a829587fe2f90a832bd3ff9d42710a4da095a2ce285b009f0c3730cd9b8e1af3eb84df6611'

警告:小心!如果你secret很简单,令牌验证过程将更容易被未经授权的入侵者破坏。

现在,将此机密存储在您的项目.env文件中:

.env
TOKEN_SECRET=09f26e402586e2faa8da4c98a35f1b20d6b033c60...

要将此令牌放入 Node.js 文件并使用它,您必须使用dotenv

  • npm install dotenv

并将其导入到您的文件中,如下所示:

const dotenv = require('dotenv');

// get config vars
dotenv.config();

// access config var
process.env.TOKEN_SECRET;

数据块的,你在你的令牌的散列可以东西或者是用户ID或用户名或更复杂的对象。在任一情况下,它应该是一个标识符用于一个特定的用户。

令牌到期时间是一个字符串,如1800秒(30分钟),即细节多久,直到令牌将是无效的。

下面是一个用于对令牌进行签名的函数示例:

function generateAccessToken(username) {
  return jwt.sign(username, process.env.TOKEN_SECRET, { expiresIn: '1800s' });
}

这可以从登录或登录用户的请求中发回:

app.post('/api/createNewUser', (req, res) => {
  // ...

  const token = generateAccessToken({ username: req.body.username });
  res.json(token);

  // ...
});

此示例usernamereq( request )获取并提供令牌作为res响应)。

这结论如何jsonwebtokencrypto以及dotenv可用于产生JWT。

第 3 步 – 验证令牌

有很多方法可以在Express.js应用程序中实现 JWT 身份验证系统

一种方法是利用Express.js 中中间件功能。

它的工作原理是当对特定路由发出请求时,您可以将(req, res)变量发送到app.get((req, res) => {}).

中间件是一个函数,它接受 的参数(req, res, next)

  • req是所发送的请求(GET,POST,DELETE,PUT,等等)。
  • res是可在方式(大量被发送回给用户的响应res.sendStatus(200)res.json()等等)。
  • next是,可以调用移动执行过去的中间件并进入实际功能app.get服务器响应。

这是用于身份验证的示例中间件函数:

const jwt = require('jsonwebtoken');

function authenticateToken(req, res, next) {
  const authHeader = req.headers['authorization']
  const token = authHeader && authHeader.split(' ')[1]

  if (token == null) return res.sendStatus(401)

  jwt.verify(token, process.env.TOKEN_SECRET as string, (err: any, user: any) => {
    console.log(err)

    if (err) return res.sendStatus(403)

    req.user = user

    next()
  })
}

使用此中间件函数的示例请求将类似于以下内容:

GET https://example.com:4000/api/userOrders
Authorization: Bearer JWT_ACCESS_TOKEN

使用该中间件的请求示例类似于以下内容:

app.get('/api/userOrders', authenticateToken, (req, res) => {
  // executes after authenticateToken
  // ...
})

此代码将验证客户端提供的令牌。如果它是有效的,它可以继续请求。如果无效,则可以作为错误处理。

第 4 步 – 处理客户端令牌

当客户端收到令牌时,他们通常希望将其存储起来,以便在以后的请求中收集用户信息。

存储身份验证令牌最流行的方式是在HttpOnly cookie 中

这是使用客户端 JavaScript 代码存储 cookie 的实现:

// get token from fetch request
const token = await res.json();

// set token in cookie
document.cookie = `token=${token}`

这种方法将响应存储在本地,以便将来向服务器发出请求时可以引用它们。

请求令牌、生成令牌、接收令牌、通过新请求传递令牌以及验证令牌的流程到此结束。

结论

在本文中,您了解了 JWT 以及将它们应用于 Node.js 应用程序的一种方法。这种方法所依赖的组合jsonwebtokencryptodotenv,和express

对于使用 JWT 的另一种方法,请参阅如何使用 JSON Web 令牌和 Passport 实现 API 身份验证

有关 JWT 的更多背景信息,请参阅“介绍”文档

如果您想了解有关 Node.js 的更多信息,请查看我们的 Node.js 主题页面以获取练习和编程项目。

觉得文章有用?

点个广告表达一下你的爱意吧 !😁