node中使用jwt实现token身份验证

node中使用jwt实现token身份验证
muCookie认证机制
- 用户向服务器发送用户名和密码
- 服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等等
- 服务器向用户返回一个session_id,写入用户的Cookie
- 用户随后的每一次请求,都会通过 Cookie,将 session_id 传回服务器
- 服务器收到 session_id,找到前期保存的数据,由此得知用户的身份
Token认证机制
我之前一直以为cookie和token是一样的,就是后台返回一个字符串保存在前端,之后的请求都带着这个字符串,后台去做校验,深入了解后知道两者是有很大区别的,是两种不同的机制。
cookie认证需要后台存一份session_id到数据库,多服务器时需要session共享。而token认证则不需要后台保存,token一般放在HTTP请求头的Authorization中。
JWT
JSON Web Token (JWT)是一种开放标准,使用数字签名安全传输信息。JWT常用场景:授权(Authorization)和信息交换(Information Exchange)。授权是最常用JWT的场景。
JWT就是一个由‘.’分隔的字符串,这个字符串包含三个部分:Header、Payload、Signature。因此JWT的形式就是xxxxx.yyyyy.zzzzz。
jwt实现token身份验证
在express项目中安装jsonwebtoken依赖
npm i jsonwebtoken --save
新建authorization.js
const jwt = require("jsonwebtoken"); const secretKey = "secretKey"; // 生成token module.exports.generateToken = function (payload) { const token = "Bearer " + jwt.sign(payload, secretKey, { expiresIn: 60 * 60, }); return token; }; // 验证token module.exports.verifyToken = function (req, res, next) { const token = req.headers.authorization.split(" ")[1]; jwt.verify(token, secretKey, function (err, decoded) { if (err) { console.log("verify error", err); return res.json({ code: "404", msg: "token无效" }); } console.log("verify decoded", decoded); next(); }); };
注意:生成 token 时加了前缀’Bearer ‘,验证时要把’Bearer ‘去掉, req.headers.authorization.split(“ “)[1],不然会出现JsonWebTokenError: invalid token的错误,验证失败。
登录接口生成token返回给前端
// login.js const express = require("express"); const router = express.Router(); const { generateToken } = require("./authorization"); // 路由 router.post("/", (req, res) => { const username = req.body.username; const password = req.body.password; const token = generateToken({ username: username }); res.json({ code: 200, msg: "登录成功", data: { token }, }); }); module.exports = router;
在app.js中注册中间件
const loginRouter = require("./login"); const auth = require("./authorization"); const userRouter = require("./user"); app.use("/api/login", loginRouter); app.use("/api/*", auth.verifyToken); // 注册token验证中间件 app.use("/api/user", userRouter);
注意:验证token的中间件要放在login路由之后,其他需要验证的路由之前
验证接口
登录:
获取用户列表:
无效token: