express 使用JWT认证

news2024/11/9 5:43:50

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.coloradmin.cn/o/2236387.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux将mysql加到systemctl命令中

linux中&#xff0c;想将mysql加到systemctl命令中&#xff0c;首先需要确定mysql的安装位置 在/etc/systemd/system目录下新建mysql.service vim /etc/systemd/system/mysql.service 复制如下内容&#xff1a;确保你自己的mysql路径是否正确 [Unit] DescriptionMySQL Server…

【Mac】安装 VMware Fusion Pro

VMware Fusion Pro 软件已经正式免费提供给个人用户使用&#xff01; 1、下载 【官网】 下拉找到 VMware Fusion Pro Download 登陆账号 如果没有账号&#xff0c;点击右上角 LOGIN &#xff0c;选择 REGISTER 注册信息除了邮箱外可随意填写 登陆时&#xff0c;Username为…

【VR】PICO 手部追踪 steamvr内无法识别,依旧识别手柄的解决方案

一、问题描述 && 原因分析 1.PICO4 手部追踪 steamvr内无法识别&#xff0c;依旧识别手柄的解决方案 尽管平放&#xff08;或关闭手柄连接&#xff09;之后&#xff0c;在 PICO 一体机中进入了手部追踪状态&#xff0c; 但只要进入 steamvr&#xff0c;就无法正确识别…

【LeetCode:64】最小路径和(Java)

题目链接 64. 最小路径和 题目描述 给定一个包含非负整数的 m x n 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 说明&#xff1a;每次只能向下或者向右移动一步。 示例 1&#xff1a; 输入&#xff1a;grid [[1,…

VUE项目是如何启动的

当我们执行npm run serve,vue就会启动到这个界面&#xff0c;这个流程是怎么的 下典型的 Vue CLI 项目结构&#xff1a; public/index.html 这是项目的主 HTML 文件&#xff0c;Vue 应用会被挂载到这个文件中的 <div id"app"></div> 元素上。 <!DO…

LeetCode100之旋转图像(48)--Java

1.问题描述 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例1 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&…

吴恩达深度学习笔记:序列模型(Sequence Models) 1.1-1.2

目录 第五门课 序列模型(Sequence Models)第一周 循环序列模型&#xff08;Recurrent Neural Networks&#xff09;1.1 为什么选择序列模型&#xff1f;&#xff08;Why Sequence Models?&#xff09;1.2 数学符号&#xff08;Notation&#xff09; 第五门课 序列模型(Sequenc…

安装和运行开发微信小程序

下载HBuilder uniapp官网 uni-app官网 微信开发者工具 安装 微信小程序 微信小程序 官网 微信小程序 配置 运行 注意&#xff1a;运行前需要开启服务端口 如果运行看不到效果&#xff0c;设置下基础库选别的版本 配置

Java反射、注解、泛型——针对实习面试

目录 Java反射、注解、泛型什么是反射&#xff1f;反射有什么优缺点&#xff1f;优点缺点 什么是泛型?泛型的优点泛型的实现 泛型怎么使用&#xff1f;泛型类泛型方法泛型接口类型参数命名约定泛型的类型限定泛型的通配符 什么是泛型擦除机制&#xff1f;为什么要擦除&#xf…

【SpringMVC】——Cookie和Session机制

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;实践 1&#xff1a;获取URL中的参数 &#xff08;1&#xff09;PathVariable 2&…

webWorker基本用法

我们都知道js是一个单线程的语言&#xff0c;当线程堵塞时&#xff0c;可能会导致页面无法正常交互&#xff0c;如一些复杂的可视化处理。即使是异步处理&#xff0c;也只是将其暂存到任务队列中去&#xff0c;等主线程执行完后依然会从任务队列中取过去。 为此&#xff0c;js提…

一文学习Android中的Property

在 Android 系统中&#xff0c;Property 是一种全局的键值对存储系统&#xff0c;允许不同组件和进程间以轻量级的方式进行数据传递。它主要用于系统配置、状态标识等场景&#xff0c;使得不同进程能够通过属性的设置或获取来通信。property 的核心特性是快速、高效&#xff0…

使用PEFT在多个AMD GPU上进行StarCoder的指令微调

Instruction fine-tuning of StarCoder with PEFT on multiple AMD GPUs — ROCm Blogs 2024年4月16日&#xff0c;由 Douglas Jia撰写。 在这篇博客中&#xff0c;我们将向您展示如何使用指令-答案对数据集在AMD GPU上微调StarCoder基础模型&#xff0c;以便它能够根据指令生…

后台管理系统窗体程序:文章管理 > 文章列表

目录 文章列表的的功能介绍&#xff1a; 1、进入页面 2、页面内的各种功能设计 &#xff08;1&#xff09;文章表格 &#xff08;2&#xff09;删除按钮 &#xff08;3&#xff09;编辑按钮 &#xff08;4&#xff09;发表文章按钮 &#xff08;5&#xff09;所有分类下拉框 &a…

微软的新模拟器将为 Windows on Arm 带来更多游戏

微软正在测试一项重大的 Windows on Arm 更新&#xff0c;以便让更多 x64 软件和游戏在配备高通 Snapdragon X Elite 或 X Plus 处理器的 Copilot Plus PC 上的 Prism 仿真下运行。 该功能是 Windows 11 Insider Preview Build 27744 的一部分&#xff0c;已向 Canary Channel …

NVR小程序接入平台/设备EasyNVR多品牌NVR管理工具/设备汇聚公共资源场景方案全析

随着信息技术的飞速发展&#xff0c;视频监控已经成为现代社会安全管理和业务运营不可或缺的一部分。特别是在公共资源管理方面&#xff0c;视频监控的应用日益广泛&#xff0c;涵盖了智慧城市、智能交通、大型企业以及校园安防等多个领域。NVR小程序接入平台EasyNVR作为一款功…

从单层到 MVC,再到 DDD:架构演进的思考与实践

引言 在日常开发中&#xff0c;我们之前工作中经常接手的大多数都是传统 MVC 架构体系的项目。然而&#xff0c;随着现在分布式和微服务架构的普及&#xff0c;越来越多的项目开始重构、拆分&#xff0c;传统的 MVC 架构也逐渐向 DDD 架构演进。为什么需要将传统架构重构为 DD…

CDN到底是什么?

文章目录 CDN到底是什么&#xff1f;一、引言二、CDN的基本概念1、CDN的定义2、CDN的作用3、代码示例&#xff1a;配置CNAME记录 三、CDN的工作原理1、请求流程2、代码示例&#xff1a;DNS解析过程3、完整的CDN工作流程 四、总结 CDN到底是什么&#xff1f; 一、引言 在互联网…

uniapp—android原生插件开发(3Android真机调试)

本篇文章从实战角度出发&#xff0c;将UniApp集成新大陆PDA设备RFID的全过程分为四部曲&#xff0c;涵盖环境搭建、插件开发、AAR打包、项目引入和功能调试。通过这份教程&#xff0c;轻松应对安卓原生插件开发与打包需求&#xff01; 一、打包uniapp资源包&#xff1a; 打包…

嵌入式采集网关(golang版本)

为了一次编写到处运行&#xff0c;使用纯GO编写&#xff0c;排除CGO&#xff0c;解决在嵌入式中交叉编译难问题 硬件设备&#xff1a;移远EC200A-CN LTE Cat 4 无线通信模块&#xff0c;搭载openwrt操作系统&#xff0c;90M内存