JSON Web Token (JWT) 是一种用于在各方之间安全传输信息的紧凑且安全的声明。JWT 可以通过 HTTP 请求发送,并且通常用于实现无状态的认证机制(即服务器不需要保存会话状态)。JWT 是一种紧凑且自包含的令牌格式,通常用于在客户端和服务器之间传递经过认证和授权的信息。
1.安装
npm i jsonwebtoken
:下载jwt。
2.导入
const jwt = require("jsonwebtoken")
:导入jwt并赋值给一个变量。
3.jwt.sign()
生成token
jwt.sign(PayloadData,SECRET_KEY,{expiresIn: 3600})
:生成带载荷、密钥、过期时间的token。
jwt.sign()的参数
PayloadData
:载荷数据,表示要存储在token中的信息。必须为对象格式,如:{openid: req.openid, userName: req.nickName }
。在verify
验证方法的回调内获取。SECRET_KEY
:用于签名的密钥,用户自定义或者通过算法生成。Object
:第三个参数为配置对象,最常用的就是expiresIn
表示token过期时间(单位秒)。
const router = require("express").Router();
const jwt = require("jsonwebtoken");
router.post("/login", async (req, res) => {
// sign()内 第一个参数表示要存储在token中的信息(在验证verify方法内返回的user内展示所以得为对象形式) 第二个参数表示代表了用于签名的密钥 第三个参数表示jwt过期时间单位秒
const token = jwt.sign({ openid: req.openid },process.env.JWT_SECRET_KEY,{ expiresIn: 60 * 60 });
res.json({
code: 200,
msg: '登录成功',
token,
openid: req.openid
})
})
4.jwt.verify()
验证token的合法性和完整性,使用全局中间件验证token是否合法并允许特定路由绕过验证
jwt.verify(token, SECRET_KEY,(err,user) => {})
:验证JWT的合法性和完整性。
jwt.verify()的参数
token
:需要验证的token。SECRET_KEY
:用于签名的密钥,用户自定义或者通过算法生成。需要与生成签名时的秘钥一样。(err,user) => {}
:回调函数。err
报错信息,user
解码后的载荷数据。
使用全局中间件验证所有接口中token是否合法并准许特定路由绕过验证
app.use((req, res, next) => {})
:使用全局中间件验证所有接口的req
请求报文中的token
是否合法,如果合法则通过next()
放行。在回调中写相应逻辑可以绕过特定路由的验证。
const express = require("express");
const jwt = require("jsonwebtoken");
const app = express();
// JWT 验证中间件
function authenticateToken(req, res, next) {
const authHeader = req.headers["authorization"];
const token = authHeader;
if (token == null) return res.sendStatus(401); // 如果没有提供 token,则返回 401 Unauthorized
// verify()验证JWT的合法性和完整性 第一个参数要解析的token 第二个参数是密钥 第三个参数是回调函数(err,user)
jwt.verify(token, process.env.JWT_SECRET_KEY, (err, user) => {
if (err) return res.sendStatus(403); // 如果 token 无效或已过期,则返回 403 Forbidden
req.user = user; // 将解码后的用户信息附加到请求对象上
console.log(user);
next();
});
}
// 设置全局中间件验证所有接口请求头是否包含token并合法,但允许特定路由绕过验证
app.use((req, res, next) => {
const publicRoutes = ["/login"]; // 允许特定路由绕过验证
const routeNeedsAuth = !publicRoutes.includes(req.path);
if (routeNeedsAuth) {
authenticateToken(req, res, next);
} else {
next();
}
});