自学内容网 自学内容网

express 使用JWT认证

1、JWT的理解

JWT 的组成部分: 分别是 Header(头部)、Payload(有效荷载)、Signature(签名) 三者之间使用英文的"."分隔,

Pyload 部分才是真正的用户信息,他是用户信息经过加密之后生成的字符串
Header 和 Signature 是 安全性相关的部分,只是为了保证 Token 的安全性

在这里插入图片描述

使用方式:
客户端收到服务器返回的 JWT 之后,通常会将它储存在 localStorage 或 sessionStorage 中。
此后,客户端每次与服务器通信,都要带上这个 JWT 的字符串,从而进行身份认证。推荐的做法是把 JWT 放在 HTTP 请求头的 Authorization 字段中,格式如下:

Authorization:Bearer <token>

2、安装

jsonwebtoken :生成JWT字符串
express-jwt :用于将JWT字符串解析还原成JSON对象

npm install jsonwebtoken express-jwt

3、使用

3.1导入

// 导入用于生成JWT字符串的包
const jwt = require("jsonwebtoken");
// 导入用户客户端发送过来的JWT字符串,解析还原成JSON对象的包
const { expressjwt } = require("express-jwt");

3.2定义密钥

为了保证 JWT 字符串的安全性,防止 JWT 字符串在网络传输过程中被别人破解,我们需要专门定义一个用于加密和解密
的 secret 密钥:
① 当生成 JWT 字符串的时候,需要使用 secret 密钥对用户的信息进行加密,最终得到加密好的 JWT 字符串
② 当把 JWT 字符串解析还原成 JSON 对象的时候,需要使用 secret 密钥进行解密

//定义secret密钥,建议将密钥命名为secretKey
const secretKey = "jwt NO1"; // 自定义

3.3 解析jwt 注册中间件

// 将JWT字符串还原为json对象
//  expressjwt({ secret: secretKey, algorithms: ["HS256"] }) 用来解析token的中间件
// .unless({ path: [/^\/api\//] }) 用来指定哪些接口不需要访问权限
// 注意:只要配置成功了 express-jwt 这个中间件,就可以把解析出来的用户信息,挂在到req.auth上

app.use(
  expressjwt({ secret: secretKey, algorithms: ["HS256"] }).unless({
    path: [/^\/api\//],
  })
);

3.3 使用

  // 用户登陆成功之后,生成JWT字符串,通过token属性响应给客户端
  // 调用jwt.sign() 生成jwt字符串,三个参数分别是:用户信息对象,加密密钥,配置对象

  const tokenStr = jwt.sign({ username: userinfo.username }, secretKey, {
    expiresIn: "30s",
  });
  

4、捕获解析失败的错误

// 使用全局错误处理中间件,捕获解析JWT失败后产生的错误
app.use((err, req, res, next) => {
  if (err.name === "UnauthorizedError") {
    return res.send({
      status: 401,
      message: "无效的token",
    });
  }
  res.send({
    status: 500,
    message: "未知的错误",
  });
});

全部代码

const express = require("express");
// 导入用于生成JWT字符串的包
const jwt = require("jsonwebtoken");
// 导入用户客户端发送过来的JWT字符串,解析还原成JSON对象的包
const { expressjwt } = require("express-jwt");

const app = express();
const port = 3000;

//1、 解析post表单数据的中间件
app.use(express.urlencoded({ extended: false }));
app.use(express.json());

// 2、定义secret密钥,建议将密钥命名为secretKey
const secretKey = "jwt NO1"; // 自定义

// 3、将JWT字符串还原为json对象
//  expressjwt({ secret: secretKey, algorithms: ["HS256"] }) 用来解析token的中间件
// .unless({ path: [/^\/api\//] }) 用来指定哪些接口不需要访问权限
// 注意:只要配置成功了 express-jwt 这个中间件,就可以把解析出来的用户信息,挂在到req.auth上

app.use(
  expressjwt({ secret: secretKey, algorithms: ["HS256"] }).unless({
    path: [/^\/api\//],
  })
);

app.post("/api/login", (req, res) => {
  const userinfo = req.body;

  if (userinfo.username !== "admin" || userinfo.password != "000000") {
    return res.send({
      status: 400,
      message: "登录失败",
    });
  }
  // 用户登陆成功之后,生成JWT字符串,通过token属性响应给客户端
  // 调用jwt.sign() 生成jwt字符串,三个参数分别是:用户信息对象,加密密钥,配置对象
  // 注意:千万不要把密码写入token中
  const tokenStr = jwt.sign({ username: userinfo.username }, secretKey, {
    expiresIn: "120s",
  });

  res.send({
    status: 200,
    msg: "登录成功",
    token: tokenStr,
  });
});
// 前端请求需要在请求头带上Authorization:Bearer 获得的token
app.post("/getUserInfo", (req, res) => {
  res.send({
    status: 200,
    data: req.auth,
  });
});

// 使用全局错误处理中间件,捕获解析JWT失败后产生的错误
app.use((err, req, res, next) => {
  if (err.name === "UnauthorizedError") {
    return res.send({
      status: 401,
      message: "无效的token",
    });
  }
  res.send({
    status: 500,
    message: "未知的错误",
  });
});

app.listen(port, () => console.log(`Example app listening on port ${port}!`));



原文地址:https://blog.csdn.net/IT_iosers/article/details/143626260

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!