We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JWT(JSON Web Token),本质就是一个字符串书写规范,如下图,作用是用来在用户和服务器之间传递安全可靠的信息
在目前前后端分离的开发过程中,使用token鉴权机制用于身份验证是最常见的方案,流程如下:
token
Token,分成了三部分,头部(Header)、载荷(Payload)、签名(Signature),并以.进行拼接。其中头部和载荷都是以JSON格式存放数据,只是进行了编码
Token
.
JSON
每个JWT都会带有头部信息,这里主要声明使用的算法。声明算法的字段名为alg,同时还有一个typ的字段,默认JWT即可。以下示例中算法为HS256
alg
typ
JWT
{ "alg": "HS256", "typ": "JWT" }
因为JWT是字符串,所以我们还需要对以上内容进行Base64编码,编码后字符串如下:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
载荷即消息体,这里会存放实际的内容,也就是Token的数据声明,例如用户的id和name,默认情况下也会携带令牌的签发时间iat,通过还可以设置过期时间,如下:
id
name
iat
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }
同样进行Base64编码后,字符串如下:
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
签名是对头部和载荷内容进行签名,一般情况,设置一个secretKey,对前两个的结果进行HMACSHA25算法,公式如下:
secretKey
HMACSHA25
Signature = HMACSHA256(base64Url(header)+.+base64Url(payload),secretKey)
一旦前面两部分数据被篡改,只要服务器加密用的密钥没有泄露,得到的签名肯定和之前的签名不一致
Token的使用分成了两部分:
借助第三方库jsonwebtoken,通过jsonwebtoken 的 sign 方法生成一个 token:
jsonwebtoken
sign
第一个参数指的是 Payload
第二个是秘钥,服务端特有
第三个参数是 option,可以定义 token 过期时间
const crypto = require("crypto"), jwt = require("jsonwebtoken"); // TODO:使用数据库 // 这里应该是用数据库存储,这里只是演示用 let userList = []; class UserController { // 用户登录 static async login(ctx) { const data = ctx.request.body; if (!data.name || !data.password) { return ctx.body = { code: "000002", message: "参数不合法" } } const result = userList.find(item => item.name === data.name && item.password === crypto.createHash('md5').update(data.password).digest('hex')) if (result) { // 生成token const token = jwt.sign( { name: result.name }, "test_token", // secret { expiresIn: 60 * 60 } // 过期时间:60 * 60 s ); return ctx.body = { code: "0", message: "登录成功", data: { token } }; } else { return ctx.body = { code: "000002", message: "用户名或密码错误" }; } } } module.exports = UserController;
在前端接收到token后,一般情况会通过localStorage进行缓存,然后将token放到HTTP 请求头Authorization 中,关于Authorization 的设置,前面要加上 Bearer ,注意后面带有空格
localStorage
HTTP
Authorization
axios.interceptors.request.use(config => { const token = localStorage.getItem('token'); config.headers.common['Authorization'] = 'Bearer ' + token; // 留意这里的 Authorization return config; })
使用 koa-jwt 中间件进行验证,方式比较简单
koa-jwt
/ 注意:放在路由前面 app.use(koajwt({ secret: 'test_token' }).unless({ // 配置白名单 path: [/\/api\/register/, /\/api\/login/] }))
获取token用户的信息方法如下:
router.get('/api/userInfo',async (ctx,next) =>{ const authorization = ctx.header.authorization // 获取jwt const token = authorization.replace('Beraer ','') const result = jwt.verify(token,'test_token') ctx.body = result
注意:上述的HMA256加密算法为单秘钥的形式,一旦泄露后果非常的危险
HMA256
在分布式系统中,每个子系统都要获取到秘钥,那么这个子系统根据该秘钥可以发布和验证令牌,但有些服务器只需要验证令牌
这时候可以采用非对称加密,利用私钥发布令牌,公钥验证令牌,加密算法可以选择RS256
RS256
优点:
缺点:
The text was updated successfully, but these errors were encountered:
No branches or pull requests
一、是什么
JWT(JSON Web Token),本质就是一个字符串书写规范,如下图,作用是用来在用户和服务器之间传递安全可靠的信息
在目前前后端分离的开发过程中,使用
token
鉴权机制用于身份验证是最常见的方案,流程如下:Token
,分成了三部分,头部(Header)、载荷(Payload)、签名(Signature),并以.
进行拼接。其中头部和载荷都是以JSON
格式存放数据,只是进行了编码header
每个JWT都会带有头部信息,这里主要声明使用的算法。声明算法的字段名为
alg
,同时还有一个typ
的字段,默认JWT
即可。以下示例中算法为HS256因为JWT是字符串,所以我们还需要对以上内容进行Base64编码,编码后字符串如下:
payload
载荷即消息体,这里会存放实际的内容,也就是
Token
的数据声明,例如用户的id
和name
,默认情况下也会携带令牌的签发时间iat
,通过还可以设置过期时间,如下:同样进行Base64编码后,字符串如下:
Signature
签名是对头部和载荷内容进行签名,一般情况,设置一个
secretKey
,对前两个的结果进行HMACSHA25
算法,公式如下:一旦前面两部分数据被篡改,只要服务器加密用的密钥没有泄露,得到的签名肯定和之前的签名不一致
二、如何实现
Token
的使用分成了两部分:生成 token
借助第三方库
jsonwebtoken
,通过jsonwebtoken
的sign
方法生成一个token
:第一个参数指的是 Payload
第二个是秘钥,服务端特有
第三个参数是 option,可以定义 token 过期时间
在前端接收到
token
后,一般情况会通过localStorage
进行缓存,然后将token
放到HTTP
请求头Authorization
中,关于Authorization
的设置,前面要加上 Bearer ,注意后面带有空格校验token
使用
koa-jwt
中间件进行验证,方式比较简单获取
token
用户的信息方法如下:注意:上述的
HMA256
加密算法为单秘钥的形式,一旦泄露后果非常的危险在分布式系统中,每个子系统都要获取到秘钥,那么这个子系统根据该秘钥可以发布和验证令牌,但有些服务器只需要验证令牌
这时候可以采用非对称加密,利用私钥发布令牌,公钥验证令牌,加密算法可以选择
RS256
三、优缺点
优点:
缺点:
参考文献
The text was updated successfully, but these errors were encountered: