当前位置: 首页 > article >正文

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}!`));



http://www.kler.cn/a/385873.html

相关文章:

  • SpringMVC数据校验、数据格式化处理、国际化设置
  • 【C++】深入理解 C++ 优先级队列、容器适配器与 deque:实现与应用解析
  • 计算机网络 (3)计算机网络的性能
  • 利用云计算实现高效的数据备份与恢复策略
  • Rust学习(五):泛型、trait
  • RabbitMQ 与 PHP Swoole 实现
  • 低空经济之星eVTOL研发技术详解
  • 越权访问漏洞
  • 基于MFC实现的赛车游戏
  • 大神狂秀技术 成功让三星手机用上macOS
  • 【hdfs】【hbase】【大数据技术基础】实践二 HBase Java API编程
  • 2024 CSS - 保姆级系列教程三 - 选择器与布局详解
  • 【MySQL】——数据库恢复技术
  • 数仓工具—Hive语法之窗口函数窗口范围/边界 range between和rows between
  • 黑马程序员Redis学习【持续更新】
  • 数据发生变化时(DOM)视图没有更新的原因及解决方案 - 2024最新版前端秋招面试短期突击面试题【100道】
  • 移动应用开发项目——图书影片管理系统【安卓项目|前后端】
  • Ubuntu /etc/sudo.conf is owned by uid 1000, should be 0 的一种解决方法
  • 掌握 .NET 8 中最小 API 的单元和集成测试:高质量代码的最佳实践
  • CTF —— 网络安全大赛
  • ABAP开发-12、Dialog屏幕开发_1
  • 设计模式-构建者
  • IO作业day4
  • redis:list列表命令和内部编码
  • jenkins使用slave节点进行node打包报错问题处理
  • 【JAVA毕业设计】基于Vue和SpringBoot的技术交流分享平台