在现代化的 Web 开发中,RESTful API 已经成为了一种流行的架构风格。它是一种面向资源的设计风格,其中每个资源都有一个唯一的 URI,并且使用标准 HTTP 方法(GET、POST、PUT 和 DELETE)进行访问。
随着 Web 应用程序的不断增长和发展,身份认证和授权成为了安全的重要组成部分,特别是在 RESTful API 架构中。一个解决这个问题的流行方法是 JWT(JSON Web Token)身份认证。
本文将介绍 JWT 身份认证是什么,为什么应该使用它以及如何在 RESTful API 中使用它。
JWT 身份认证是什么?
JWT 身份认证(JSON Web Tokens authentication)是一种基于 JSON 的电子令牌,可以用于验证身份、授权和其他一些安全信息。JWT 身份认证使用一个 JSON 格式的字符串来传输信息,因此可以在不需要会话状态的情况下轻松地在跨域应用程序之间传递身份验证信息。
JWT 身份认证包含三个部分:Header、Payload 和 Signature。Header 指定该令牌的类型和所用的加密算法。Payload 包含所需的信息,例如用户 ID、过期时间和其他元数据。Signature 用于验证令牌未被篡改。
JWT 的优点
- 对比传统 Cookie 身份认证,无需在服务器上存储会话状态,所以可扩展性更好;
- 可以跨越多个域名传递信息,而 Cookie 只有在自己的域名下有效。
如何在 RESTful API 中实现 JWT 身份认证?
在 RESTful API 中实现 JWT 身份认证,需要使用一个库来帮助我们创建、验证和解码 JWT 令牌。在这个例子中,我们会使用一个叫做 jsonwebtoken 的 Node.js 库。
步骤一:安装依赖库
在终端执行以下命令来安装 jsonwebtoken:
npm install jsonwebtoken
步骤二:生成 JWT 令牌
当用户登陆时,我们需要生成一个 JWT 令牌。这个令牌应该包含与该用户相关的一些信息,例如其 ID 和角色。以下是如何使用 jsonwebtoken 库来生成 JWT 令牌的示例代码:
const jwt = require('jsonwebtoken'); // 这些是用户数据 const userId = '123456'; const userRole = 'admin'; // 签发一个新的 JWT 令牌 const token = jwt.sign({ userId, userRole }, 'your-secret-key', { expiresIn: '1h' });
jwt.sign
方法需要三个参数:
- 要加密的数据,通常是一个包含所有用户信息的对象;
- 一个秘钥,用于对 JWT 令牌进行签名,此秘钥不可泄漏;
- 过期时间,这里是 1 小时。
执行完这段代码之后,将会生成一个加密后的 JWT 令牌。您可以将它传递给客户端,并在之后的请求中包含它。
步骤三:在 API 中验证 JWT 令牌
在每个需要验证用户身份的请求中,我们需要验证 JWT 令牌的有效性。接下来,我们将创建一个中间件来完成这个任务。中间件将会在每个请求之前执行,检查 JWT 令牌是否有效。以下是如何在 Node.js 应用程序中实现 JWT 令牌验证的示例代码:
const jwt = require('jsonwebtoken'); function verifyJWT(req, res, next) { const authHeader = req.headers.authorization; if (authHeader) { const token = authHeader.split(' ')[1]; jwt.verify(token, 'your-secret-key', (err, user) => { if (err) { return res.sendStatus(403); } req.user = user; next(); }); } else { res.sendStatus(401); } }
这个函数检查请求的头部中是否包含一个授权标头(Authorization header)。如果有,那么将令牌从标头中提取出来,并使用 jwt.verify
方法来验证令牌的有效性。
验证令牌的方法需要三个参数:
- 要验证的令牌;
- 与令牌签名时使用的秘钥相同的秘钥;
- 回调函数,如果令牌有效,则返回用户信息对象。
在 verifyJWT
函数中,我们检查是否有错误,如果有错误,则返回一个 403 响应,表明请求不被允许。如果令牌有效,则将用户信息添加到请求对象,并调用 next()
,这将使请求继续向它本来应该去的路径继续执行。
步骤四:在 API 中使用 JWT 令牌
在每个 API 路由的最上面加上 verifyJWT
中间件,就可以保证只有经过身份验证的用户才能访问该路由。以下是示例代码:
const router = require('express').Router(); const verifyJWT = require('./verifyJWT'); // 这个路由需要身份验证 router.get('/protectedRoute', verifyJWT, (req, res) => { res.send(`Welcome to the protected route, ${req.user.userId}!`); });
在这个例子中,路由 /protectedRoute
只允许具有有效 JWT 令牌的用户访问。
总结
JWT 身份验证是一种现代化、灵活且安全的方法,可以让我们在无状态的应用程序中轻松地验证、授权和传输用户数据。在 RESTful API 中运用 JWT 身份验证,我们可以使用 jsonwebtoken 库来生成、验证和解码 JWT 令牌,并使用可重用的中间件来保护需要身份验证的 API 路由。这可以帮助我们更轻松地开发安全的、可扩展的 Web 应用程序。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a0d9dbadd4f0e0ff90c494