使用cookie-parser
cookie-parser 是一个用于解析 HTTP 请求中的 Cookie 的中间件,常用于 Node.js 的 Express 框架中。它能够解析请求头中的 Cookie 字段,并将其转换为 JavaScript 对象,方便开发者访问和操作。
加入cookie-parser中间件
js
const cookieParser = require("cookie-parser");
app.use(cookieParser(yunjin));//加入密钥
加入之后,会在req对象中注入cookies属性,用于获取所有请求传递过来的cookie
加入之后,会在res对象中注入cookie方法,用于设置cookie
原来的写法:
js
ter.post(
"/login",
synchandler(async (req, res) => {
const result = await adminServ.login(req.body.loginId, req.body.loginPwd);
if (result) {
// 登录成功
res.header("set-cookie", `token=${result.id}; path=/; domain=localhost; max-age=3600`);
}
return result;
}
));
加入cookie-parser组件之后:
js
ter.post(
"/login",
synchandler(async (req, res) => {
const result = await adminServ.login(req.body.loginId, req.body.loginPwd);
if (result) {
// 登录成功
res.cookie("token",result.id,{
path:"/",
domain:"localhost",
maxAge:1000*60*60*24*7,//毫秒数
});
}
return result;
}
));
登录成功后给予token
通过cookie给予适配的浏览器,但是给适配的其他终端的通过header给予的
改进:
js
ter.post(
"/login",
synchandler(async (req, res) => {
const result = await adminServ.login(req.body.loginId, req.body.loginPwd);
if (result) {
const value = result.id;
// 登录成功
res.cookie("token",value,{
path:"/",
domain:"localhost",
maxAge:1000*60*60*24*7,//毫秒数
});
res.header("authorization", value);
}
return result;
}
));
对后续请求进行认证
后续每次请求验证的时候先解析cookie或header中的token,然后验证token,通过则继续后续处理,不通过则给予错误 tokenMiddle.js认证检验
js
const {getErr}=require("./getSendResult")
const {pathToRegexp}=require("path-to-regexp");
const crypt=require("./util/crypt");
const needTokenApi = [
{method:"POST",path:"/api/student"},
{method:"PUT",path:"/api/student/:id"},
];
//解析token
module.exports = async (req, res, next) => {
const apis=needTokenApi.filter((api)=>{
const reg=pathToRegexp(api.path);
return api.method===req.method&®.text(req.path);
});
if(apis.length===0){
next();
return;
}
let token =req.cookies.token;
if(!token){
//从header中的authorization中获取
token=req.header.authorization;
}
if(!token){
//没有认证
handleNonToken(req,res,next);
return;
}
const userId=crypt.decrypt(token);
req.userId=userId;
next();
};
//处理没有认证的情况
function handleNonToken(req,res,next){
res
.status(403)
.send(getErr("no token",403));
}
init.js使用
js
const {asyncHandler}=require('../orm/api/getSendResult')
const crypt=require("./util/crypt")
router.post(
"/login",
asyncHandler(async (req, res) => {
const result = await adminServ.login(req.body.loginId, req.body.loginPwd);
if (result) {
let value = result.id;
value=crypt.encrypt(value.toString());
// 登录成功
res.cookie("token",value,{
path:"/",
domain:"localhost",
maxAge:1000*60*60*24*7,//毫秒数
signed:true,
});
res.header("authorization", value);
}
return result;
}
));
module.exports = router
crypt.js手动写加密和解密
js
//使用对称加密算法:aes 128
//128位的密钥
const secret = Buffer.from("mm7h3ck87ugk914a");
const crypto = require("crypto");
//准备一个iv,随机变量
const iv = Buffer.from(
//写法
// Math.random().toString(36).slice(-8) + Math.random().toString(36).slice(-8)
"jxkvxz9704u3m8c4"
);
exports.encrypt = function (str) {
const cry = crypto.createCipheriv("aes-128-cbc", secret, iv);
let result = cry.update(str, "utf-8", "hex");
result += cry.final("hex");
return result;
};
exports.decrypt = function (str) {
const decry = crypto.createDecipheriv("aes-128-cbc", secret, iv);
let result = decry.update(str, "hex", "utf-8");
result += decry.final("utf-8");
return result;
};
getSendResult.js处理方法
js
exports.getErr = function (err = "server internal error", errCode = 500) {
return {
code: errCode,
msg: err,
};
};
exports.getResult = function (result) {
return {
code: 0,
msg: "",
data: result,
};
};
exports.asyncHandler = (handler) => {
return async (req, res, next) => {
try {
const result = await handler(req, res, next);
res.send(exports.getResult(result));
} catch (err) {
next(err);
}
};
};