实现登录和认证

使用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&&reg.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);
      }
  };
};
相关推荐
m0_7381207244 分钟前
应急响应——知攻善防Web-3靶机详细教程
服务器·前端·网络·安全·web安全·php
程序员爱钓鱼8 小时前
Node.js 编程实战:文件读写操作
前端·后端·node.js
PineappleCoder8 小时前
工程化必备!SVG 雪碧图的最佳实践:ID 引用 + 缓存友好,无需手动算坐标
前端·性能优化
JIngJaneIL8 小时前
基于springboot + vue古城景区管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
敲敲了个代码8 小时前
隐式类型转换:哈基米 == 猫 ? true :false
开发语言·前端·javascript·学习·面试·web
澄江静如练_9 小时前
列表渲染(v-for)
前端·javascript·vue.js
JustHappy9 小时前
「chrome extensions🛠️」我写了一个超级简单的浏览器插件Vue开发模板
前端·javascript·github
Loo国昌9 小时前
Vue 3 前端工程化:架构、核心原理与生产实践
前端·vue.js·架构
sg_knight9 小时前
拥抱未来:ECMAScript Modules (ESM) 深度解析
开发语言·前端·javascript·vue·ecmascript·web·esm