Nodejs -- 一文学会如何在Express中使用JWT(json web token)

news2024/10/7 16:22:43

文章目录

  • 在Express中使用JWT
    • 1 安装JWT相关的包
    • 2 导入JWT相关的包
    • 3 定义secret密钥
    • 4 在登录成功后生成JWT字符串
    • 5 将JWT字符串还原为JSON对象
    • 6 使用req.user获取用户信息
    • 7 捕获解析JWT失败后产生的错误
    • 8 完整代码示例

在Express中使用JWT

1 安装JWT相关的包

运行如下命令,安装如下两个JWT相关的包:

npm install jsonwebtoken express-jwt

其中:

  • jsonwebtoken用于生成JWT字符串
  • express-jwt用于将JWT字符串解析还原成Json对像

2 导入JWT相关的包

//  1.导入用于生成JT字符串的包
const jwt = require('jsonwebtoken')

//2.导入用于将客户端发送过来的JwT字符串,解析还原成JS0N对象的包
const { expressjwt: jwt } = require("express-jwt");

3 定义secret密钥

为了保证JWT字符串的安全性,防止JWT字符串在网络传输过程中被别人破解,我们需要专门定义一个用于加密和解密的secret密钥:

  • 当生成JWT字符串的时候,需要使用secret密钥对用户的信息进行加密,最终得到加密好的JWT字符串
  • 当把JWT字符串解析还原成json对象的时候,需要使用secret密钥进行解密

密钥可以是任意的字符串,越复杂越好

//3.secret密钥的本质:就是一个字符串
const secretKey = 'Nodejs No1 ^_^'

4 在登录成功后生成JWT字符串

调用jsonwebtoken包提供的sign()方法,将用户的信息加密成JWT字符串,响应给客户端:

千万不要把密码加密到token中

//登录接口
app.post('/api/login', (req, res) => {
    // ··省略登录失败情况下的代码
	//用户登录成功之后,生成JWT字符串,通过token属性响应给客户端
    res.send({
        status: 200,
        message: '登录成功!',
		//调用jwt.sign()生成JWT字符串,三个参数分别是:用户信息对像、加密密钥、配置对橡
        token: jwt.sign({username: userinfo.username}, secretKey, {expiresIn: '30s'})
    })
})

完整代码:

const express = require("express")
const jwt = require("jsonwebtoken")
const {urlencoded} = require("express");

const app = express()
app.use(urlencoded({extended: false}))

const secretKey = "kkk *_*"

app.get("/login", (req, res) => {
    if (req.body.username === 'admin' && req.body.password === 'admin') {
        const tokenStr = jwt.sign({username: req.body.username}, secretKey, {expiresIn: "24h"})
        res.send({
            status: 200,
            msg: 'success',
            token: tokenStr
        })
    } else {
        req.send({
            msg: "账号或者密码错误"
        })
    }

})

app.listen(80, () => {
    console.log("server start")
})

启动后通过接口测试,得到结果如下:

image-20221129203329971

5 将JWT字符串还原为JSON对象

客户端海次在访问那些有权限接口的时候,都需要主动通过请求头中的Authorization字段,将Token字符串发送到服务器进行身份认证。

此时,服务器可以通过express-jwt这个中间件,自动将客户端发送过来的Token解析还原成json对像:

express-jwt7版本之后用法发生了变化,参考express-jwt - npm

const { expressjwt } = require("express-jwt");

// 使用app.use()来注册中间件
// .unless({path:[/^\/api\//]})用来指定哪些接口不需要访问权限
app.use(
    expressjwt({
        secret: secretKey,
        algorithms: ["HS256"]
  	}).unless({path: [/^\/api\//]})
)

6 使用req.user获取用户信息

express-jwt这个中间件配置成功之后,即可在那些有权限的接口中,使用req.user对象,来访问从JWT字符串中解析出来的用户信息了,示例代码如下:

只有配置好了express-jwt中间件之后才能通过req.user获取用户信息,

//这是一个有权限的API接口
app.get('/admin/getinfo', (req, res) => {
    console.log(re.user)
    res.send({
        status: 200,
        message: '获取用户信息成功!',
        data: req.auth
    })
})

7 捕获解析JWT失败后产生的错误

当使用express-jwt解析Token字符串时,如果客户端发送过来的Token字符串过期或不合法,会产生一个解析失败的错误,影响项目的正常运行。我们可以通过Express的错误中间件,捕获这个错误并进行相关的处理,示例代码如下:

记得放在最后

app.use((err, req, res, next) => {
    //token解析失败导致的错误
    if (err.name === 'UnauthorizedError') {
        return res.send({status: 401, message: '无效的token'})
    }

    //其它原因导致的错误
    res.send({status: 500, message: '未知错误'})
})

8 完整代码示例

const express = require("express")
const jwt = require("jsonwebtoken")
const {urlencoded} = require("express");
const {expressjwt} = require("express-jwt")

const app = express()
const secretKey = "kkk *_*"

app.use(urlencoded({extended: false}))

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

app.get("/api/login", (req, res) => {
    if (req.body.username === 'admin' && req.body.password === 'admin') {
        const tokenStr = jwt.sign({username: req.body.username}, secretKey, {expiresIn: "24h"})
        res.send({
            status: 200,
            msg: 'success',
            token: tokenStr
        })
    } else {
        req.send({
            msg: "账号或者密码错误"
        })
    }
})

app.get("/user/getInfo", (req, res) => {
    res.send({
        status: 200,
        msg: "success",
        data: res.auth
    })
})

app.listen(80, () => {
    console.log("server start")
})

app.use((err, req, res, next) => {
    //token解析失败导致的错误
    if (err.name === 'UnauthorizedError') {
        return res.send({status: 401, message: '无效的token'})
    }

    //其它原因导致的错误
    res.send({status: 500, message: '未知错误'})
})

登录结果:

image-20221129204114170

获取信息成功结果:

记得将登陆中得到的token放到Authorization中,并且前面加上Bearer

image-20221129204245018

token有误的情况:

image-20221129204233335

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/46772.html

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

相关文章

Java基础概念-03-字面量

在有些资料中,会把字面量叫做,常量,或字面值常量,但最正确的叫法还是,字面量 小数在 Java 中也称为浮点数 下面是课本中的介绍: 常量是指在程序运行过程中,其值不能被修改的量,Java…

C# 移动飞机

一 实现一个飞机游戏,可以使用键盘控制飞机的移动。 二 游戏的显示 GameView:负责游戏的显示; 使用自定义绘制的技术,将飞机场地绘制出来; cells:3x3的单元格; OnSizeChanged:计算单元格的位置和大小&…

用VS软件开发“中国象棋“游戏<笔记摘录>

整体架构如上 1.很直观地去看这个中国象棋的界面,数一下它有多少行和多少列. 10行,9列:要注意这里数的是安放象棋的位置,有10行9列 这里我们首先想到的必然是二维数组,每一个行列交叉的点都设置成二维数组a[i][j]这样的格式,以此来确定棋盘上面每一个棋子的位置和走向. 我们…

01 导论【计量经济学及stata应用】

配套教材:《计量经济学及stata应用.陈强.2015.高等教育出版社》 官方课程链接:http://www.econometrics-stata.com/ 官方公众微信号:econometrics-stata 写博客的初衷就是为了督促自己把所学的知识进行整理和完善,我将于接下来的时…

性能测试-CPU性能分析,用户态us高,初步定位到代码行

监控工具安装 Grafana:安装请看我上一篇文章性能测试-JMeter influxdb grafana性能测试监控平台-食用指南_Tommy.IT的博客-CSDN博客JMeter测试脚本跑起来,在influxdb服务看看数据里面的数据,原来influxdb的jmeter库里面没有表,当JMeter脚本运…

PyCharm+PyQT5之三界面与逻辑的分离

之二的例程已经实现了界面与逻辑的分离,所建立的 Dialog Mainwindow 或者 widgets 等,界面改变其主调程序(暂且这样叫)更改,或者不需要大规模更改, 主调函数的程序是这样的 import sys import FistUI from PyQt5.QtWidgets import QApplication, QMainWindow,QDialog if __nam…

KubeSphere 多行日志采集方案深度探索

作者:大飞哥,视源电子运维工程师,KubeSphere 用户委员会广州站站长 采集落盘日志 日志采集,通常使用 EFK 架构,即 ElasticSearch,Filebeat,Kibana,这是在主机日志采集上非常成熟的方案,但在容器…

React Server Component: 混合式渲染

作者:谢奇璇 React 官方对 Server Comopnent 是这样介绍的: zero-bundle-size React Server Components。 这是一种实验性探索,但相信该探索是个未来 React 发展的方向,与 React Server Component 相关的周边生态正在积极的建设当中。 术语…

R语言主成分分析可视化(颜值高,很详细)

文章目录PCA特征值可视化提取变量结果变量结果可视化变量和主成分的cos2可视化变量对主成分的贡献可视化Dimension description提取样本结果样本结果可视化样本的cos2可视化样本对主成分的贡献可视化biplot参考资料网络上很多R语言教程都是基于R语言实战进行修改,今…

Mysql密码忘记后怎么重置密码,mysql8之后有改动

mysql8之前的修改方式: 1.管理员身份打开cmd:然后关闭mysql,停止MySQL服务,输入 net stop mysql 停止服务 2.切换到MySQL的bin文件下,输入mysqld --console --skip-grant-tables --shared-memory。 3上个窗口保留不要…

四种类型自编码器AutoEncoder理解及代码实现

自编码器(AE) 自编码器的结构和思想 结构 自编码器是一种无监督的数据压缩和数据特征表达方法。自编码器是神经网络的一种,经过训练后的能尝试将输入复制到输出。自编码器由编码器和解码器组成。如下图所示: 自编码器指的是试图…

电脑键盘功能基础知识,快速入门,抓住这份详细教程

在互联网生活发达的今天,电脑已经成为了学习工作的必备工具。而用来操作电脑的关键,就是我们经常使用的键盘和鼠标。最近有不少的小伙伴来私信小编,希望小编做一个电脑键盘功能基础知识介绍的详细教程。这不,小编应大家要求&#…

视频编解码 - RTP 与 RTCP

目录 RTP 实时传输协议 RTCP协议 将H264 RTP打包 RTP 实时传输协议 音视频数据传输,先将原始数据经过编码压缩后,将码流打包成一个个RTP包,再将码流传输到接收端。 打包的作用 接收端要正确地使用这些音视频编码数据,不仅仅需…

深度学习之路=====12=====>>MNasNet(tensorflow2)

简介 原文: MnasNet: Platform-Aware Neural Architecture Search for Mobile 来源: CVPR2019 作者: Google (Mingxing Tan, Bo Chen, Ruoming Pang, Vijay Vasudevan, Mark Sandler, Andrew Howard, Quoc V. Le) 摘要: 使用神经结构搜索(neural archit…

界面控件DevExpress WPF的主题设计器,可轻松完成应用主题研发

DevExpress WPF拥有120个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 DevExpress WPF的The…

一文详解|高校到底如何开展数据分类分级?

数据安全是高校的生命线,在数据安全合规要求不断升级的大背景下,加强数据有效保护,确保数据安全共享应用,已成为高校信息化建设的前线。 安全高楼平地起,作为数据安全建设的基础工作,通过数据分类分级&…

1541_AURIX_TriCore内核架构_内核调试控制器CDC

全部学习汇总: GitHub - GreyZhang/g_tricore_architecture: some learning note about tricore architecture. 这一份笔记可能会是我近段时间来最后的一份内核学习笔记了。我看了下内核手册分为上下两部分,而下卷主要的内容其实是讲解指令集&#xff0c…

如何用CSS画一个三角形?

hello,大家好,最近在看前端的八股,里面有这样一道题,如何用CSS画出三角形?我想以这个题为例,仔细讲一下这个题的技巧,以及对这道题拓展一下,即如何画出圆形和椭圆形? 首…

GFS分布式

GFS是什么? 1.1 简单介绍 这个问题说大也大,说小也小。GFS是Google File System的缩写,字面意义上就是Google的文件系统,技术层面上来讲,GFS是Google在2003年前后创建的可扩展分布式文件系统 ,用来满足 Goo…

SpringBoot 接收客户端提交数据/参数会使用到相关注解

目录 一.基本介绍 二.接收参数相关注解应用实例 1.需求: 2.应用实例演示 2.1演示PathVariable 使用 2.2.演示RequestHeader 使用 2.3演示RequestParam 使用 2.4演示CookieValue 使用 2.5演示RequestBody 使用 2.6演示RequestAttribute,SessionAttribute 使…