JWT(JSON Web Token)是一种用于实现身份验证和授权的开放标准。它是一种基于JSON的安全传输数据的方式,由三部分组成:头部、载荷和签名。
一、JWT 的前世:传统身份信息验证面临的篡改、伪造问题
二、JWT 的本质:使用签名机制解决安全问题
三、JWT 的组成:由三个部分组成的字符串


jwt里需要包含生效时间和过期时间,传回服务器之后由服务器判断是否过期。
用户主动登出就直接由客户端删除token。
JWT不是加密方法,它只是把业务中后端原本需要用Redis记录的一些数据换了一种方式保存和读取,作用是减少数据库查询。它只能防止别人修改其他人的数据,没有办法防止别人复制或者读取。

使用jsonwebtoken模块,你可以在Node.js应用程序中轻松生成和验证JWT。以下是jsonwebtoken库的使用步骤:
安装jsonwebtoken模块:在命令行中运行npm install jsonwebtoken来安装jsonwebtoken模块。
导入jsonwebtoken模块:在你的Node.js应用程序中,使用require语句导入jsonwebtoken模块。
const jwt = require('jsonwebtoken');
sign方法生成JWT。该方法接受三个参数:载荷(Payload)、密钥和可选的配置对象。载荷是一个包含有关用户/客户端的信息的对象。const payload = {
userId: '123456789',
username: 'example_user'
};
const secretKey = 'your_secret_key';
const token = jwt.sign(payload, secretKey, { expiresIn: '1h' });
上述代码将生成一个JWT,其中包含了userId和username信息,使用了一个密钥进行签名,并设置了过期时间为1小时。生成的JWT将作为一个字符串存储在token变量中。
verify方法验证JWT的有效性。该方法接受三个参数:要验证的JWT、密钥和一个可选的回调函数。const token = 'your_generated_jwt';
jwt.verify(token, secretKey, (err, decoded) => {
if (err) {
// JWT验证失败
console.log('JWT verification failed.');
} else {
// JWT验证成功
console.log('JWT verified successfully.');
console.log(decoded); // 解码后的JWT负载
}
});
上述代码将验证传入的JWT是否有效,并使用提供的密钥进行签名验证。如果JWT有效,verify方法回调函数中的decoded参数将包含解码后的JWT负载信息。如果JWT无效,则会在回调函数中得到一个错误。
以下是 JWT 的一个简单的封装:
//jsonwebtoken 封装
const jsonwebtoken = require("jsonwebtoken")
// 设置密钥
const secret = "anydata"
const JWT = {
// 生成 token
generate(value,expires){
// value 数据,expires 过期时间
return jsonwebtoken.sign(value,secret,{expiresIn:expires})
},
// 校验 token
verify(token){
// 放在 try...catch... 中,防止报错
try{
return jsonwebtoken.verify(token,secret)
}catch(error){
return false
}
}
}
module.exports = JWT
const token = JWT.generate('xx', '10s')
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoieHgiLCJpYXQiOjE2OTc0Mzk3MTEsImV4cCI6MTY5NzQzOTcyMX0.vfcaK_tHfbD-58nqcDRopg516jngqWJhw6zr229zACM
// header.数据.签名
console.log(JWT.verify(token))
// node 中间件校验
app.use((req,res,next)=>{
// 如果token有效 ,next()
// 如果token过期了, 返回401错误
if(req.url==="/login"){
next()
return;
}
const token = req.headers["authorization"]?.split(" ")[1]
if(token){
var payload = JWT.verify(token)
// console.log(payload)
if(payload){
const newToken = JWT.generate({
_id:payload._id,
username:payload.username
},"1d")
res.header("Authorization",newToken)
next()
}else{
// errCode 和 errInfo 是 network 的 preview 中返回的数据
res.status(401).send({errCode:"-1",errInfo:"token过期"})
}
}
})
//生成token
const token = JWT.generate({
_id: result[0]._id,
username: result[0].username
}, "1d")
res.header("Authorization", token)
token 作为用户的数据标识,在接口层面起到了接口权限控制的作用,也就是说后端有很多接口都需要通过查看当前请求头信息中是否含有 token 数据,来决定是否正常返回数据。
//前端拦截
import axios from 'axios'
// Add a request interceptor
axios.interceptors.request.use(function (config) {
const token = localStorage.getItem("token")
config.headers.Authorization = `Bearer ${token}`
return config;
}, function (error) {
return Promise.reject(error);
});
// Add a response interceptor
axios.interceptors.response.use(function (response) {
const {authorization } = response.headers
authorization && localStorage.setItem("token",authorization)
return response;
}, function (error) {
const {status} = error.response
if(status===401){
// 移除本地失效的 token 值,由于过期而失效
localStorage.removeItem("token")
window.location.href="/login"
}
return Promise.reject(error);
});
业务逻辑:
简单总结:
配置 jwt util,controller 中使用 jwt:
Bearer ${token}