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

6,359 阅读2分钟

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. 验证接口

登录:

image.png

获取用户列表:

image.png

无效token:

image.png

参考链接

jwt.io/introductio…

github.com/auth0/node-…

www.ruanyifeng.com/blog/2018/0…