登录和认证-服务器开发

57 阅读1分钟

jsonwebtoken库

npm express-jwt

示例util/index.js

const jwt = require("jsonwebtoken");
const secret = "yuanjin";
const token = jwt.sign(
    {
    id: 1,
    name: "成哥",
    },
    secret,
    {
    expiresIn: 0,
    }
});

try {
    const decoded = jwt.verify(token, secret);
    console.log(decoded);
} catch {
    console.log("jwt无效");
}

颁发jwt

  • 确定过期时间
  • 确定主体
  • 确定密钥
  • 确定传输方式
    • session
    • cookie
const secret = "yuanjin";
const cookieKey = "token";
const jwt = require("jsonwebtoken");

//颁发jwt
exports.publish = function (res, maxAge = 3600 * 24, info = {}) {
    const token = jwt.sign(info, secret, {
        expiresIn: maxAge,
    });
    //添加到cookie
    res.cookie(cookieKey, token, {
        maxAge: maxAge * 1000,
        path: "/",
    });
    //添加其他传输
    res.header("authorization", token);
};

admin.js

const express = require("express");
const router = express.Router();
const adminServ = require("../../services/adminService");
const { asyncHandler } = require("../getSendResult");
const cryptor = require("../../util/crypt");
const jwt = require("../jwt")

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());
      //登录成功
      jwt.publish(res,undefined,{id:value});
    }
    return result;
  })
);

module.exports = router;

认证jwt

  • 获取jwt
    • 从cookie中获取
    • 从authorization中获取
      • 带bearer
      • 不带bearer
  • 验证jwt
exports.verify = function (req) {
    let token;
    //尝试从cookie中获取
    token = req.cookies.token; //cookie中没有
    if (!token) {
        //尝试从header中获取
        token = req.headers.authorization;
        if (!token) {
            //没有token
            return null;
        }
        // authorization: bearer token
        token = token.split(" ");
        token = token.length === 1 ? token[0] : token[1];
    }
    try {
        const result = jwt.verify(token, secret);
        return result;
    } catch(err) {
        return null;
    }
};

使用tokenMiddleware.js

const { getErr } = require("./getSendResult");
const { pathToRegexp } = require("path-to-regexp");
const jwt = require("./jwt");
const needTokenApi = [
    { method: "POST", path: "/api/student" },
    { method: "PUT", path: "/api/student/:id" },
];

// 用于解析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;
    }

    const result = jwt.verify(req);
    if (result) {
        //认证通过
        req.userId = result.id;
        next();
    } else {
        //认证失败
        handleNonToken(req, res, next);
    }
};
//处理没有认证的情况
function handleNonToken(req, res, next) {
    res.status(403).send(getErr("you don't have any token to access the api", 403));
}

添加whoam接口

admin.js

router.get("whoami",asyncHandler(async(req,res)=>{
   return await adminSery.getAdminById(req,userId)
}))