什么是jwt?
JWT(JSON Web Token)是一种开放的标准(RFC 7519),用于在网络应用间传递信息的一种方式。它是一种基于JSON的安全令牌,用于在客户端和服务器之间传输信息。 jwt.io/
JWT由三部分组成,它们通过点(.)进行分隔:
Header(头部):包含了令牌的类型和使用的加密算法等信息。通常采用Base64编码表示。
Payload(负载):包含了身份验证和授权等信息,如用户ID、角色、权限等。也可以自定义其他相关信息。同样采用Base64编码表示。
Signature(签名):使用指定的密钥对头部和负载进行签名,以确保令牌的完整性和真实性。
JWT的工作流程如下:
用户通过提供有效的凭证(例如用户名和密码)进行身份验证。
服务器验证凭证,并生成一个JWT作为响应。JWT包含了用户的身份信息和其他必要的数据。
服务器将JWT发送给客户端。
客户端在后续的请求中,将JWT放入请求的头部或其他适当的位置。
服务器在接收到请求时,验证JWT的签名以确保其完整性和真实性。如果验证通过,服务器使用JWT中的信息进行授权和身份验证。
全局中间件
//伪代码, 全局中间件就是每次触发请求都会走的生命周期
function verifyToken(req, res, next) {
console.log('req===>')
next();
}
app.use(verifyToken)
用到的依赖
jsonwebtoken 生成token的库
Reset client 是vsode插件模拟发送请求
代码编写
import express from 'express'
import jwt from 'jsonwebtoken';
const app = express();
app.use(express.json());
app.use(function (req, res, next) { //跨域设置
res.header("Access-Control-Allow-Origin", req.headers.origin);
// res.header("Access-Control-Allow-Origin", '*');
res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header("Access-Control-Allow-Credentials", "true");
if (req.method.toLowerCase() == 'options') {
res.send(200);
return;
}
var method = req.method.toLowerCase();
/* if (method === 'post') {
req.yyhParams = req.body;
//get请求
} else if (method === 'get') {
req.yyhParams = req.query;
} */
next();
});
// 你的密钥,用于签名 JWT
const secretKey = 'yourSecretKey';
// 创建一个模拟的用户数据库
const users = [
{ username: 'john', password: 'password' }
];
// 身份验证路由
app.post('/login', (req, res) => {
const { username, password } = req.body;
// 查找用户
const user = users.find(u => u.username === username && u.password === password);
if (!user) {
return res.status(401).send({ message: 'Invalid credentials' });
}
// 签名 JWT
const token = jwt.sign({ username: user.username }, secretKey, { expiresIn: '1m' });
res.send({ token });
});
// 验证 JWT 的中间件
function verifyToken(req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (token == null) return res.sendStatus(401);
jwt.verify(token, secretKey, (err, user) => {
if (err) return res.sendStatus(403);
req.user = user;
next();
});
}
// 应用全局中间件 所有路由都会生效
app.use(verifyToken);
// 需要验证的路由
app.get('/protected', verifyToken, (req, res) => {
console.log(req)
res.send({ message: 'Welcome to the protected route' });
});
app.get('/', (req, res) => {
res.send({ message: 'Welcome to the public route' });
});
// 启动服务器
const port = process.env.PORT || 3333;
app.listen(port, () => console.log(`Server running on port ${port}`));
- express.http模拟发送请求
POST http://localhost:3333/login HTTP/1.1
content-type: application/json
{
"username": "john",
"password": "password"
}
GET http://localhost:3333/ HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImpvaG4iLCJpYXQiOjE3MjM1MTc5ODEsImV4cCI6MTcyMzUxODA0MX0.Q1XHJBZynGn8UCPkb8pQ1UJDfsciMScShYRP1rkhibk
-
验证失败展示(未携带token或者token过期)
-
验证成功展示(携带token)