在构建 RESTful API 的过程中,身份验证是一个至关重要的问题。为了保证 API 的安全性,我们需要确保只有授权的用户才能够访问受保护的资源。JSON Web Token(JWT)是一种用于身份验证和授权的开放标准,它在 RESTful API 中被广泛采用。
本篇文章将详细探讨在 RESTful API 中如何使用 JWT 实现身份验证。我们将介绍 JWT 的基本概念和原理,并以 JavaScript 示例代码为例,为读者提供具体的指导意义。
什么是 JWT?
JWT 是一种标准化的、用于传输信息的 JSON 对象,其通常会被用来验证网络应用和跨域授权。相对于传统的 session 和 cookie,JWT 具有更加简单高效的优势。
JWT 的结构通常由三个部分构成:header、payload 和 signature。其中,header 包含了当前 JWT 的类型和算法,payload 包含了需要传递的信息,signature 则用于验证 JWT 的合法性。
下面是一个 JWT 示例:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
其中,第一部分是 header,第二部分是 payload,第三部分是 signature。需要注意的是,每个部分之间都是以英文句点“.”隔开的。
如何使用 JWT 进行身份验证?
假设我们已经在 API 中使用了 JWT 来进行身份验证,那么我们需要遵循以下步骤:
生成 Token
在用户进行登录时,我们可以通过提供合法的用户名和密码,从服务器得到一个 Token。例如:
let token = jwt.sign({ username: 'foo' }, 'secret_key', { expiresIn: '1h' });其中,sign() 函数接收三个参数:payload、secret_key 和 options。我们只需要将传递的信息附带在 payload 中,然后通过 secret_key 和选项选项来生成签名即可。
发送 Token
一旦 Token 生成成功,我们就需要将其发送给客户端。通常,我们可以将 Token 存储在客户端的 localStorage 或 cookie 中。
localStorage.setItem('token', token);验证 Token
在客户端向 API 发送请求时,我们需要将 Token 作为 Authorization 请求头发送到服务器。服务器会在返回的响应中附带一个状态码,告诉客户端当前的身份验证是否成功。
axios.get('/api/protected', {
headers: { 'Authorization': `Bearer ${token}` }
}).then(res => {
console.log(res.data);
}).catch(err => {
console.error(err);
});在 API 中验证 Token 的步骤相对来说要复杂一些,我们需要完成如下任务:
- 解析并验证 Token 的签名,如果签名无效则驳回 Token。
- 获取 Token 的 payload,验证用户是否具有足够的权限访问当前请求的资源。
- 如果所有条件都满足,则返回响应,否则返回带有错误信息的响应。
下面是一个示例的 Node.js 代码,它演示了如何在结果 API 中使用 JWT 进行身份验证。
// www.javascriptcn.com code example
const jwt = require('jsonwebtoken');
const secret_key = 'my_secret_key';
// 获取请求头中的 Token
function getTokenFromHeader(req) {
if (!req.headers.authorization) {
return null;
}
const token = req.headers.authorization.replace('Bearer ', '');
return token;
}
// 中间件:验证 Token
function authenticateToken(req, res, next) {
const token = getTokenFromHeader(req);
if (!token) {
return res.status(401).send('Access denied. No token provided.');
}
jwt.verify(token, secret_key, (err, payload) => {
if (err) {
return res.status(401).send('Invalid token.');
}
req.payload = payload;
next();
});
}
// 受保护的路由
router.get('/api/protected', authenticateToken, (req, res) => {
const payload = req.payload
res.send(`Hello, ${payload.username}!`);
});
// 登录
router.post('/api/login', (req, res) => {
const { username, password } = req.body;
if (username === 'foo' && password === 'bar') {
const token = jwt.sign({ username: 'foo' }, secret_key, { expiresIn: '1h' });
res.send({ token });
} else {
res.status(401).send('Invalid credentials.');
}
});在上述代码中,我们使用 authenticateToken() 中间件,在每个受保护的路由之前都验证 Token 的合法性。如果 Token 验证失败或 Token 未提供,则返回一个 401(Unauthorized)状态码。如果 Token 验证成功,则可以从请求中的 payload 中获取用户信息,完成后续操作。
结语
使用 JWT 进行身份验证在 RESTful API 中是一种非常流行的做法。在本文中,我们讲述了 JWT 的基本概念和工作原理,并提供了一个用于身份验证的 JavaScript 示例代码。希望这篇文章能够对你学习和使用 JWT 提供指导,并使你在构建安全 API 的路径上更稳健。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d68362a941bf7134c4ca18