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

Cookie认证机制

  1. 用户向服务器发送用户名和密码
  2. 服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等等
  3. 服务器向用户返回一个session_id,写入用户的Cookie
  4. 用户随后的每一次请求,都会通过 Cookie,将 session_id 传回服务器
  5. 服务器收到 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身份验证

  1. 在express项目中安装jsonwebtoken依赖

    npm i jsonwebtoken --save
  2. 新建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的错误,验证失败。

  3. 登录接口生成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;
  4. 在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路由之后,其他需要验证的路由之前

  5. 验证接口

登录:

获取用户列表:

无效token:

参考链接

JWT官网

node-jsonwebtoken

阮一峰-JSON Web Token 入门教程