nodejs的jwt实现
JWT
JSON Web Token(JSON Web令牌)
是一个开放标准(rfc7519),它定义了一种紧凑的、自包含的方式,用于在各方之间以JSON对象安全地传输信息。此信息可以验证和信任,因为它是数字签名的。jwt可以使用秘密〈使用HNAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名。
通过JSON形式作为Web应用中的令牌,用于在各方之间安全地将信息作为JSON对象传输。在数据传输过程中还可以完成数据加密、签名等相关处理。
JWT作用:
授权:一旦用户登录,每个后续请求将包括JWT,从而允许用户访问该令牌允许的路由,服务和资源。它的开销很小并且可以在不同的域中使用。如:单点登录。
信息交换:在各方之间安全地传输信息。JWT可进行签名(如使用公钥/私钥对),因此可确保发件人。由于签名是使用标头和有效负载计算的,因此还可验证内容是否被篡改。
JWT结构
就是令牌token,是一个String字符串,由3部分组成,中间用点隔开
令牌组成:
标头(Header)
有效载荷(Payload)
签名(Signature)
token格式:head.payload.singurater 如:xxxxx.yyyy.zzzz
案例
以下做一个简单的token签名,前端使用vue,服务器使用nodejs
功能实现,两个页面,一个登录页一个列表页,登录后返回加密token,访问列表页时需要token校验,如果校验不通过返回登录页,通过展示列表页
nodejs实现
app.js
const express = require("express"); const app = express(); const bosyParser = require("body-parser"); const jwt = require("jsonwebtoken"); //加载包 app.use(bosyParser.json()); //解析json数据 //跨域 app.use(function (req, res, next) { //设置允许跨域的域名,*代表允许任意域名跨域 res.header("Access-Control-Allow-Origin", "*"); // 例如 允许百度跨域, 把上面这行的*替换为 https://baidu.com //允许的header类型 res.header("Access-Control-Allow-Headers", "content-type"); //跨域允许的请求方式 res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS"); if (req.method.toLowerCase() == "options") { res.sendStatus(200); //让options预验证尝试请求快速结束 } next(); }); const user = { name: "zhangsan", password: "123456" }; //储存账号,模拟数据库 const theKey = "mykey";//定义密匙
//登录 app.post("/login", (req, res) => { if (JSON.stringify(user) === JSON.stringify(req.body)) { let token = jwt.sign(user.name, theKey);//生成token //账号密码正确 res.json({ code: 0, token, data: user }); } else { res.json({ code: 1, data: "账号或密码错误" }); } }); //中间件,校验token let autoCheck = (req, res, next) => { const token = req.headers.authorization && req.headers.authorization.split(" ")[1]; if (token) { req.token = token; next(); } else { res.json("token失效"); } };
//获取列表数据 app.get("/list", autoCheck, (req, res) => { const token = req.token; jwt.verify(token, theKey, (err, data) => { //data为解码之后的数据,即name if (!err) { res.json({ code: 0, data }); } else { res.json({ code: 1, data: "token签名错误" }); } }); }); app.listen(4000, () => { console.log("4000端口启动了"); });
axios添加拦截,方便操作
import axios from "axios"; //添加请求拦截,设置authorization axios.interceptors.request.use( (config) => { const token = sessionStorage.getItem("token"); if (token) { //每次请求尝试携带token config.headers.Authorization = `Bearer ${token}`; } return config; }, (err) => { return Promise.reject(err); } ); //添加响应拦截 axios.interceptors.response.use((res) => { if (res.data.code === 0) { //响应数据减少一层 return Promise.resolve(res.data); } else { return Promise.reject("请求失败"); } }); export default axios;
两个页面
login.vue
submit() { this.$axios.post('/api/login', this.user).then( (res) => { if (res.code === 0) { const { data, token } = res token && sessionStorage.setItem('token', token)//保存token data && this.$router.push('/list') } }, (err) => { console.log(err) } ) }
此处提交url:/api/login使用了代理
list.vue
mounted() { this.$axios.get('/api/list').then( (res) => { if (res.code === 0) { this.user.name = res.data } }, (err) => { console.log(err) this.$router.push('/login') } ) }
token在axios中设置了,此次不需要携带token
一个简单的登录验证token就实现了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通