介绍
JSON Web Tokens (JWTs) 支持授权和信息交换。
一个常见的用例是允许客户端在登录后保留他们的会话信息。通过在本地存储会话信息并在发出请求时将其传递给服务器进行身份验证,服务器可以相信客户端是注册用户。
在本文中,您将了解 JWT 在使用 Node.js 和 vanilla JavaScript 的服务器-客户端关系中的应用。
先决条件
要跟随本文,您需要在您的机器上安装以下内容:
- Node.js 安装在本地,您可以按照如何安装 Node.js 和创建本地开发环境来完成。
第 1 步 – 生成令牌
jsonwebtoken
是 JSON Web 令牌的实现。
您可以通过在终端中运行以下命令将其添加到您的 JavaScript 项目中:
- npm install jsonwebtoken
并将其导入到您的文件中,如下所示:
const jwt = require('jsonwebtoken');
要签署令牌,您需要有 3 条信息:
- 令牌秘密
- 要在令牌中散列的数据
- 令牌过期时间
该令牌密钥是用于加密和解密数据长随机数序列。
要生成这个秘密,一种选择是使用 Node.js 的内置crypto
库,如下所示:
> require('crypto').randomBytes(64).toString('hex')
// '09f26e402586e2faa8da4c98a35f1b20d6b033c6097befa8be3486a829587fe2f90a832bd3ff9d42710a4da095a2ce285b009f0c3730cd9b8e1af3eb84df6611'
警告:小心!如果你secret
很简单,令牌验证过程将更容易被未经授权的入侵者破坏。
现在,将此机密存储在您的项目.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);
// ...
});
此示例username
从req
( request )获取值。并提供令牌作为res
(响应)。
这结论如何jsonwebtoken
,crypto
以及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 应用程序的一种方法。这种方法所依赖的组合jsonwebtoken
,crypto
,dotenv
,和express
。
对于使用 JWT 的另一种方法,请参阅如何使用 JSON Web 令牌和 Passport 实现 API 身份验证。
有关 JWT 的更多背景信息,请参阅“介绍”文档。
如果您想了解有关 Node.js 的更多信息,请查看我们的 Node.js 主题页面以获取练习和编程项目。