nodejs 使用 JWT 实现token验证机制
1. 目前主流的Web开发模式有两种:
- 基于服务端渲染的传统Web开发模式:服务器发送给客户端的HTML页面,是在服务器通过字符串的拼接,动态生成的。因此,客户端不需要使用ajax这样的技术额外请求页面的数据,适用于
Session验证机制
。 - 基于前后端分离的新型Web开发模式:依赖于Ajax技术,就是后端只负责提供API接口,前端使用Ajax调用接口的开发模式,适用于
JWT验证机制(JSON Web Token 验证)
。
2. Session认证的局限性
- Session需要配合Cookie才能实现。由于 Cookie 默认不支持跨域访问,所以,当涉及到前端跨域请求后端接口的时候,需要做很多额外的配置,才能实现跨域 Session 认证。
注意:
- 当前端请求后端接口不存在跨域问题的时候,推荐使用
Session身份认证机制
。- 当前端需要跨域请求后端接口的时候,不推荐使用 Session身份认证机制,推荐使用
JWT认证机制
。
3. 什么是Token
JWT
(英文全称:JSON Web Token)是目前最流行的跨域认证解决方案。
使用原理
前端:初次登录时,向服务器发送账号和密码,通过验证后接收从后端返回的JWT
,并将其存储到localStorage 或sessionStorage中。之后每次发送请求,都将本地存储的JWT
放在 HTTP 请求头的 Authorization
字段中。 后端:登陆成功后,生成JWT
返回给客户端,之后每次收到请求时都校验请求头中的JWT
。
JWT组成
jwt的组成
JWT
通常由三部分组成,分别是 Header
(头部)、Payload
(有效荷载)、Signature
(签名) 。
- Header:内部包含有签名算法、Token类型。
- Payload:内部包含JWT标准数据和自定义数据。
- Signature:这部分是对前两部分的签名,防止数据的篡改。 三者之间使用英文的“.”分隔,组成
JWT
。
4. nodejs 中使用 JWT
安装相关的包
npm i jsonwebtoken express-jwt
- jsonwebtoken 用于生成 JWT 字符串
- express-jwt 用于将 JWT 字符串解析还原成 JSON 对象
导入生成token的包 && 定义密钥
为了保证JWT字符串的安全性,防止JWT字符串在网络传输过程中被人破解,我们需要专门定义一个加密和解密的secret密钥:
- 当生成JWT字符串的时候,需要使用secret密钥对用户的信息进行加密,最终得到加密的JWT字符串
- 当把jwt字符串解析还原成json对象的时候,需要使用secret密钥进行解密
// 生成token的包
const jWT = require('jsonwebtoken')
// 定义Secret密钥
const secret = 'login2023'
封装生成Token的函数
// 生成token
const createToken = (account, password) => {
let sql = `select * from user where account = '${account}' and password = '${password}'`
return conMysql(sql).then(result => {
// 调用jWT.sign()方法生成token
const token = jWT.sign({
userId: result[0].userId,// 用户相关信息
username: result[0].username,
headPortrait: result[0].headPortrait
},
secret,//密钥进行加密
{ expiresIn: "3h" } //token有效时间
)
return {
token: 'Bearer ' token //生成的token一般格式为:Bearer [token]
}
})
}
使用中间件解析Token
// 导入校验token的模块,解析JWT字符串,还原成JSON对象的模块
const {expressjwt:jwt} = require('express-jwt')
// 生成token的密钥
const secret = 'login2023'
// 无需校验token的白名单
const whiteList = ['/user/login','/user/register']
// 解析token
app.use(
jwt({
secret,
algorithms:['HS256'],//使用何种加密算法解析
})
.unless({path: whiteList})//登陆注册页无需校验
)
校验Token
// token过期或不合法
app.use((err, req, res, next) => {
if (err.name === 'UnauthorizedError'){
res.send({code:500,msg:'invalid token'}))
}
})
使用req.auth获取用户信息
当express-jwt
这个中间件配置成功后,即可在那些有权限的接口中,使用req.auth
对象,来访问从JWT字符串中解析出来的用户信息了
// 获取用户信息
if(method === 'GET' && path === '/getUser'){
return res.send({
code:200,
msg:'成功',
data:req.auth
})
}
前端使用Token
// 保存token
import axios from 'axios'
const token = axios.post('v1/login', {...}); localStorage.setItem('token', token);
localStorage.setItem('token', token);
// 使用token
const api = axios.create({
// 基础路径
baseURL: http://localhost:8000/v1,
// 请求超时时间
timeout: 5000,
})
// axios实例拦截器中添加token
request.interceptors.request.use((config) => {
if (localStorage.getItem('token')) {
config.headers.Authorization = localStorage.getItem('token') // 在请求头的 Authorization 中添加token
}
return config
})
本篇文章来至:学新通
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通
- 本文地址: https://www.swvq.com/boutique/detail/tanhcjikfj
- 联系方式: luke.wu#vfv.cc
系列文章
更多
同类精品
更多
精彩评论
-
Java 线程组构造方法源码
PHP中文网 08-30 -
C语言篇语法细节杂谈番外篇
Lonble 09-01 -
解决gradle下找不到符号错误
BananaAres 11-02 -
目标检测算法的优缺点和适用场景
A等天晴 09-24 -
我的多巴胺回来了双手奉上在rumble上下载视频的最佳秘诀
光崽子 10-01 -
thinkphp控制器的定义和使用
PHP中文网 05-28 -
60 KVM Skylark虚拟机混部-安装和配置
superman超哥 10-07 -
Word 里文字对齐4种方法推荐
码农阿宇 09-20 -
npm和node.js有什么关系吗
PHP中文网 06-21 -
Polly-故障处理和弹性应对很有一手
Code综艺圈 10-20