登录分发cookie
利用cookie-parser 中间件
安装
npm i cookie-parser
简单的使用cookie-parser
- 加入cookie-parser 中间件
- 加入之后,会在req对象中注入cookies属性,用于获取所有请求传递过来的cookie
- 加入之后,会在res对象中注入cookie方法,用于设置cookie
const cookieParser = require("cookie-parser");
app.use(cookieParser());
路由配置
router.post('/login',asyncHandler(async (req,res)=>{
console.log(req.body);
const result = await adminServ.login(req.body.loginId,req.body.loginPwd);
console.log(result);
if(result){
let value = result.id;
res.cookie("token", value, {
path: "/",
domain: "localhost",
maxAge: 7 * 24 * 3600 * 1000, //毫秒数
});
res.header("authorization", value);
}
return result;
}))
res.cookie() 只配置 浏览器客户端
如果是其他端 则需要在配置在头部 authorization
手写token中间件处理函数
先保存需要进行token认证的api路径needTokenApi
在处理函数中先用path-to-regexp插件进行对路径的解析方便进行对动态api匹配 解析出相应的正则规则 如果没有匹配到则不需要进行token认证 next()交给后面的中间件处理 否则进行token认证
const { getErr } = require("./getSendResult");
const { pathToRegexp } = require("path-to-regexp");
// const cryptor = require("../util/crypt");
const needTokenApi = [ //需要进行token认证的api路径
{ method: "POST", path: "/api/student" },
{ method: "PUT", path: "/api/student/:id" },
{ method: "GET", path: "/api/student" },
];
// 用于解析token
module.exports = (req, res, next) => {
// /api/student/:id 和 /api/student/1771
const apis = needTokenApi.filter((api) => {
const reg = pathToRegexp(api.path);
return api.method === req.method && reg.test(req.path);
});
if (apis.length === 0) {
next();
return;
}
let token = req.cookies.token;
if (!token) {
// 从header的authorization中获取
token = req.headers.authorization;
}
if (!token) {
//没有认证
handleNonToken(req, res, next);
return;
}
// const userId = cryptor.decrypt(token);
// req.userId = userId;
next();
};
//处理没有认证的情况
function handleNonToken(req, res, next) {
res
.status(403)
.send(getErr("you dont have any token to access the api", 403));
}
但是这样的cookie是明文的 不太安全 容易被伪造 最好需要进行加密
1.可以直接在res.cookie()里面配置一个signed
这样会自动给cookie加密
2.使用对称加密算法 aes 128
// 使用对称加密算法:aes 128
// 128位的秘钥
秘钥可以通过两个随机数相加产生
const secret = Buffer.from("mm7h3ck87ugk9l4a"); //秘钥
const crypto = require("crypto");
// 准备一个iv,随机向量
const iv = Buffer.from("jxkvxz97409u3m8c");
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;
};
路由的配置
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 = cryptor.encrypt(value.toString());//加密
//登录成功
res.cookie("token", value, {
path: "/",
domain: "localhost",
maxAge: 7 * 24 * 3600 * 1000, //毫秒数
});
res.header("authorization", value);
}
return result;
})
);