登录及身份验证使用 JWT 令牌技术流程以及怎么实现
时间: 2024-09-10 21:27:20 浏览: 59
使用 JWT(JSON Web 令牌)实现登录身份验证和令牌续订
JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用环境间传递声明(claims)的紧凑的自包含方式。JWT 令牌技术在登录和身份验证流程中可以提供一种安全且简洁的方法来处理身份验证和信息交换。以下是使用 JWT 进行登录及身份验证的一般流程:
1. 用户登录:用户通过登录界面输入用户名和密码,后端系统验证这些凭据的正确性。
2. 生成 JWT 令牌:一旦用户身份被验证,后端服务就会创建一个 JWT 令牌,并将其返回给用户。该令牌通常包含三个部分:
- Header(头部):通常包含两部分信息:令牌类型(即 JWT),以及所使用的签名算法,如 HMAC SHA256 或 RSA。
- Payload(载荷):包含所谓的“声明”(claims),声明是关于实体(通常是用户)和其他数据的声明。claims可以是用户的权限、角色、令牌的有效时间等。
- Signature(签名):为了创建签名部分,您必须有编码后的 Header 和 Payload,然后使用密钥对它们进行签名。签名用于验证消息在此过程中未被篡改,并且在从服务器发送至客户端时保持了完整性。
3. 存储和传输:用户收到 JWT 令牌后,通常将其存储在客户端的本地存储中(例如 localStorage 或 sessionStorage),并在后续的请求中将其添加到 HTTP 头的 Authorization 字段中(通常以 "Bearer token" 的格式),用以访问受保护的资源。
4. 服务器验证:每当用户尝试访问一个受保护的路由或资源时,服务器端会解码并验证 JWT 令牌的有效性。服务器会检查签名、令牌的过期时间以及其他声明信息。
5. 响应:如果 JWT 令牌有效,服务器将处理用户请求并返回相应的数据或资源;如果无效,则返回错误信息。
以下是使用 Node.js 和 Express 实现 JWT 身份验证的一个简单例子:
```javascript
const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
// 假设我们有一个用户模型和验证用户的方法
const User = require('./models/User');
const verifyUser = require('./utils/verifyUser');
const app = express();
app.use(express.json());
// 登录接口
app.post('/login', async (req, res) => {
const { username, password } = req.body;
const user = await User.findOne({ username });
if (user && bcrypt.compareSync(password, user.password)) {
const token = jwt.sign({ id: user._id }, 'secret_key', { expiresIn: '1h' });
res.status(200).json({ token });
} else {
res.status(401).send('用户名或密码错误');
}
});
// 受保护的路由
app.get('/protected', verifyUser, (req, res) => {
// 这里处理业务逻辑
res.status(200).send('protected route accessed');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
// 使用中间件来验证 JWT
const verifyUser = (req, res, next) => {
try {
const token = req.headers.authorization.split(' ')[1]; // 假设请求中携带的格式为 'Bearer token'
const decoded = jwt.verify(token, 'secret_key');
req.userId = decoded.id;
next();
} catch (error) {
res.status(401).send('Invalid token');
}
};
```
阅读全文