Nodejs -- 一文学会如何在Express中使用JWT(json web token)
创始人
2024-02-29 23:53:11
0

文章目录

  • 在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

相关内容

热门资讯

常用商务英语口语   商务英语是以适应职场生活的语言要求为目的,内容涉及到商务活动的方方面面。下面是小编收集的常用商务...
六年级上册英语第一单元练习题   一、根据要求写单词。  1.dry(反义词)__________________  2.writ...
复活节英文怎么说 复活节英文怎么说?复活节的英语翻译是什么?复活节:Easter;"Easter,anniversar...
2008年北京奥运会主题曲 2008年北京奥运会(第29届夏季奥林匹克运动会),2008年8月8日到2008年8月24日在中华人...
英语道歉信 英语道歉信15篇  在日常生活中,道歉信的使用频率越来越高,通过道歉信,我们可以更好地解释事情发生的...
六年级英语专题训练(连词成句... 六年级英语专题训练(连词成句30题)  1. have,playhouse,many,I,toy,i...
上班迟到情况说明英语   每个人都或多或少的迟到过那么几次,因为各种原因,可能生病,可能因为交通堵车,可能是因为天气冷,有...
小学英语教学论文 小学英语教学论文范文  引导语:英语教育一直都是每个家长所器重的,那么有关小学英语教学论文要怎么写呢...
英语口语学习必看的方法技巧 英语口语学习必看的方法技巧如何才能说流利的英语? 说外语时,我们主要应做到四件事:理解、回答、提问、...
四级英语作文选:Birth ... 四级英语作文范文选:Birth controlSince the Chinese Governmen...
金融专业英语面试自我介绍 金融专业英语面试自我介绍3篇  金融专业的学生面试时,面试官要求用英语做自我介绍该怎么说。下面是小编...
我的李老师走了四年级英语日记... 我的李老师走了四年级英语日记带翻译  我上了五个学期的小学却换了六任老师,李老师是带我们班最长的语文...
小学三年级英语日记带翻译捡玉... 小学三年级英语日记带翻译捡玉米  今天,我和妈妈去外婆家,外婆家有刚剥的`玉米棒上带有玉米籽,好大的...
七年级英语优秀教学设计 七年级英语优秀教学设计  作为一位兢兢业业的人民教师,常常要写一份优秀的教学设计,教学设计是把教学原...
我的英语老师作文 我的英语老师作文(通用21篇)  在日常生活或是工作学习中,大家都有写作文的经历,对作文很是熟悉吧,...
英语老师教学经验总结 英语老师教学经验总结(通用19篇)  总结是指社会团体、企业单位和个人对某一阶段的学习、工作或其完成...
初一英语暑假作业答案 初一英语暑假作业答案  英语练习一(基础训练)第一题1.D2.H3.E4.F5.I6.A7.J8.C...
大学生的英语演讲稿 大学生的英语演讲稿范文(精选10篇)  使用正确的写作思路书写演讲稿会更加事半功倍。在现实社会中,越...
VOA美国之音英语学习网址 VOA美国之音英语学习推荐网址 美国之音网站已经成为语言学习最重要的资源站点,在互联网上还有若干网站...
商务英语期末试卷 Part I Term Translation (20%)Section A: Translate ...