关于可以实现前端跨域请求后端接口的JWT认证机制

JWT是目前最流行的跨域认证解决方案

JWT的工作原理

当用户在客户端操作个人信息第一次提交账号和密码到服务端时,服务器端会验证账号和密码,验证通过后会将用户的信息对象进行加密,加密后生成Token字符串,此时服务器会将生成的Token字符串发送给客户端,把Token字符串存储在客户端的LocalStorage或SessionStorage中。
当客户端再一次与服务端通信发起请求时,都会携带这个Token字符串,并通过请求头的Authorization字段,将Token发送给客户端,在服务器会把Token字符串进行解密,还原成用户输入的信息对象,并进行用户的身份认证,认证成功后,服务器会对当前用户生成特定的响应内容,把当前用户对应的页面内容响应给浏览器。
在这里插入图片描述

Bearer Token(Token 令牌)

了解了JWT的工作原理后,我们要知道Bearer Token(Token 令牌)的概念:
为了验证使用者的身份,需要客户端向服务器端提供一个可靠的验证信息,称为Token,这个token通常由Json数据格式组成,通过hash散列算法生成一个字符串,所以称为Json Web Token(Json表示令牌的原始值是一个Json格式的数据,web表示是在互联网传播的,token表示令牌,简称JWT)

JWT的组成

JWT由三部分组成: Header(头部)、Payload(有效荷载)、Signature(签名) 中间用点分隔

  • Payload 载荷部分是真正的用户信息,它是用户信息经过加密之后生成的字符串
    标准中注册的声明(建议但不强制使用):

iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token。

  • HeaderSignature 是安全性相关的部分,只是为了保证 Token 的安全性

一段Token字符串如下:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNjAwODY0MjI4LCJleHAiOjE2MDA4NjQ4Mjh9.fcLkE5FH4u5fLVCvNXM4xFXxFj3JNaoLzpe7qdz8fug

在 express 中验证 JWT的认证机制

下面我们在erpress中测试JWT的认证机制:
在Node.js中测试,首先我们要安装两个加密和解密JWT相关的包:

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

TODO_01:安装并导入 JWT 相关的两个包,分别是 jsonwebtoken 和 express-jwt

const jwt = require('jsonwebtoken') //对用户数据进行jwt加密
const expressJWT = require('express-jwt') //解密

TODO_02:定义 secret 密钥,建议将密钥命名为 secretKey 密钥字符可以随便设置

var secretkey = 'dfhdsafdsgfhf' //密钥 提高安全性

TODO_03:在登录成功之后,调用 jwt.sign() 方法生成 JWT 字符串,并通过 token 属性发送给客户端

res.send({
    status: 200,
    message: '登录成功!',
    token: 'Bearer' + jwt.sign({ username: userinfo.username }, secretkey, { expiresIn: '600s' })
  })

TODO_04:注册将 JWT 字符串解析还原成 JSON 对象的中间件

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

TODO_05:使用 req.user 获取用户信息,并使用 data 属性将用户信息发送给客户端

res.send({
    status: 200,
    message: '获取用户信息成功!',
    data: req.user // 要发送给客户端的用户信息
  })

TODO_06:使用全局错误处理中间件,捕获解析 JWT 过期失败后产生的错误

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

注意:secretkey是保存在服务器端的,jwt的签发生成也是在服务器端的,secretkey就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secretkey, 那就意味着客户端是可以自我签发jwt了。

postman中测试JWT结果

在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值