JWT认证机制

JWT(JSON Web Token):解决跨域认证的一种方案。
工作原理:
在这里插入图片描述
JWT会将用户的信息通过Token字符串的形式,保存在客户端浏览器中,然后服务器通过还原Token字符串的形式来认证用户的身份。
JWT的组成部分:
通常由三部分组成,分别是Header(头部)、Payload(有效荷载)、Signature(签名)。三者之间用英文的“ ."分隔。格式如下:

Header.Payload.Signature

其中Payload部分才是真正的用户信息,它是用户信息经过加密之后生成的字符串。Header和Signature是安全性相关的部分,只是为了保证Token的安全性。

JWT的使用方式:
客户端收到服务器返回的JWT之后,通常会将它储存在localStoragesessionStorage中。
此后,客户端每次与服务器通信,都要带上这个JWT的字符串,从而进行身份认证。推荐的做法是把JWT放在HTTP请求头的Authorization字段中,格式如下:

Authorization:Bearer <token>

在Express中使用JWT
1.安装JWT相关包:

 npm install isonwebtoken express-jwt

其中:
jsonwebtoken:用于生成JWT字符串;
express-jwt:用于将JWT字符串解析还原成JSON

2.导入JWT相关的包:

// 导入用于生成JWT字符串的包
const jwt = require('jsonwebtoken')
// 导入用于将客户端发送过来的JWT字符串,解析还原成JSON对象的包
const expressJWT = require('express-jwt')

3.定义secret密钥
为了保证WT字符串的安全性,防止JWT字符串在网络传输过程中被别人破解。我们需要专门定义一个用于加密解密的secret密钥:
(1)当生成JWT字符串的时候,需要使用secret密钥对用户的信息进行加密,最终得到密好的JWT字符串;
(2)当把JWT字符串解析还原成JSON对象的时候,需要使用secret密钥进行解密

// secret密钥的本质:就是一个字符串
const secretKey = '字符串'

4.在登录成功后生成JWT字符串
调用jsonwebtoken包提供的sign()方法,将用户的信息加密成JWT字符串,响应给客户端。

// 登录接口
app.post('/api/login',function(req,res) {
	if (err) return console.log(err.message) // 失败
	// 登录成功后,生成JWT字符串,通过token属性响应给客户端
	res.send( {
		status:200,
		message:'登录成功',
		// 调用jwt.sign()生成JWT字符串,三个参数分别是:用户信息对象,加密密钥,配置对象
		token:jwt.sign({ username:userinfo.username},secreKey,{expiresIn:'30s'})
	})
})

5.将JWT字符串还原为JSON对象
客户端每次在访问那些有权限接口的时候,都需要主动通过请求头中的Authorization字段,将Token字符串发送到服务器进行身份认证。
此时,服务器可以通过express-jwt这个中间件,自动将客户端发送过来的Token解析还原成JSON对象:

// 使用app.use()来注册中间件
// expressJWT({ secret:secretKey })就是用来解析Token中间件的
//.unless({path:[/^\/api\//] })用来指定哪些接口不需要访问权限
app.use(expressJWT({secret:secretKey}).unless({path:[/^\/api\//] }))

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

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

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: '未知错误'
	})
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值