jwt实现token鉴权(nodejs|jwt实现token鉴权(nodejs koa)
为什么需要token?
【jwt实现token鉴权(nodejs|jwt实现token鉴权(nodejs koa)】在后台管理系统中,我们通常使用cookie-session的方式用于鉴权,如何通过cookie、session鉴权(nodejs/koa) 但这种方式存在着以下问题
- 比如cookie的容量太小
- 浏览器端和app端发送http请求时携带cookie会有差异
- 分布式系统和服务器集群保证如何保证sessionId是相同
数据格式实现token的鉴权方式通常使用jwt,即json web token,jwt的格式如 xxx.yyy.zzz
- xxx的部分用来描述使用什么样的加密方式
- yyy的部分是携带的数据,比如id,name,通常还会携带 iat(issue at)发布时间, exp(expiration time)过期时间,用于鉴权的时候判断此token是否在有效期内,以上xxx和yyy都是对json数据以base64编码的方式进行转换
- zzz是对xxx.yyy再加上密钥进行加密,加密的方式在header中。
文章图片
- header 部分
{"alg":"HS256","typ":"JWT"} // base64编码结果:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
- playload部分
{"id":1,"name":"Alice","iat":1630814528619,"exp":1630816048023} // base64编码结果:eyJpZCI6MSwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNjMwODE0NTI4NjE5LCJleHAiOjE2MzA4MTYwNDgwMjN9
- signature部分
// 加密结果为:B2df_qYbivZcjpJ_QtIyRu4ts6n_pwxlSQl41Bpsxz8
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNjMwODE0NTI4NjE5LCJleHAiOjE2MzA4MTYwNDgwMjN9.B2df_qYbivZcjpJ_QtIyRu4ts6n_pwxlSQl41Bpsxz8
文章图片
可以看到jwt的header和payload都是用base64进行编码的,也可解码,所以并不能存放重要信息,而jwt数据的传递也不是为了加密重要信息,jwt的singature部分是需要通过密钥来加密的,只要密钥不泄露,身份就不容易被伪造。
如何使用
jwt可以用于客户端向服务器发送的请求的时候携带,放置到 header中,使用 authorization 这个字段,使用 Bearer的方式
文章图片
公钥和私钥
- 对称加密算法,只用一个密钥加密和解密
- 非对称加密算法,公钥用于加密,私钥用于解密
openssl中可以生成公钥和私钥
// 生成公钥
genrsa -out private.key 2048
// 生成私钥
rsa -in private.key -puout -out public.key
分别生成 public.key 和 private.key 文件
服务器如何鉴权
用户登录成功后,服务器返回token,以Koa来做个演示
const jwt = require("jsonwebtoken")
const PRIVATE_KEY = fs.readFileSync('./private.key')const user = { id: 1, name: 'kiki'}
const token = jwt.sign(user, PRIVATE_KEY, {
expiresIn: 10, // 单位s
algorithm: "RS256"
})
客户端将在header中的authorization携带token数据,服务器校验token的有效性和正确性
const PUBLIC_KEY = fs.readFileSync('./public.key')const authorization = ctx.headers.authorization
const token = authorization.replace("Bearer ", "")// 如果失败会直接报错, 所以需要捕获
try {
const result = jwt.verify(token, PUBLIC_KEY, {
algorithms: ["RS256"]
})
// 拿到的信息是 { id: 1, name: 'kiki', iat: '', exp: ''}
} catch(error){}
推荐阅读
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 孩子不是实现父母欲望的工具——林哈夫
- opencv|opencv C++模板匹配的简单实现
- Node.js中readline模块实现终端输入
- java中如何实现重建二叉树
- 人脸识别|【人脸识别系列】| 实现自动化妆
- paddle|动手从头实现LSTM
- pytorch|使用pytorch从头实现多层LSTM