JWT是什么?
JWT(JSON Web Token)是一个公开的标准(RFC 7519),标准规定信息通过json的格式传递,这个信息是被加密过的,加密的姿势大致分为两种,一种是共同约定一个secret key,使用HMAC SHA256等等方式加密,还有一种就是public/private key,使用RSA方式加密。
JWT的结构有三部分组成,我们可以先看一个header中的加密后的JWT Token:
你会发现,他有两个英文句号分割了整个Token,其实JWT的结构有三部分组成:
。Header
。Payload
。Signature
Header举个例子:
{
"alg": "HS256",
"typ": "JWT"
}
这里alg表示加密方式,也可以是RSA
base64UrlEncode(header)
PayLoad又分为三部分:注册请求、公有请求、私有请求。
eg:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
这个sub就是注册请求部分,iss (issuer), exp (expiration time), sub (subject), aud(audience)
这个name就是公有请求部分,有点类似于协议的关键字(RFC 7519)
这个admin才是我们自己的东西,可以是一个True,也可以是一个用户的手机号,后端用这个手机号去db中查询该手机号是否有访问的权限
base64UrlEncode(payload)
Signature:
Signature = HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
最后把三部分用.拼接起来就生成了
为什么要使用JWT?
原始的session、cookie的验权方式太麻烦和难以拓展了,比如后端是服务器集群,那可能要做session的持久化等等,还有一些跨域cookie无法传递的问题,索性服务端就不保存session了,把数据保存在客户端, 每次请求由客户端把信息发送过来,前后端开发起来都比较爽
JWT的验权信息写在哪里?
写在http请求header里面:Authorization: Bearer <token>
哪有人会问了,我写在query string里面行不行?我为啥非要在token前面加个“Bearer ”啊?不加难道没办法验权?
当时是可以验权的,只要后端保证跟你的验证逻辑保持一致其实就好了,但是RFC 7519协议里面把Authorization和Bearer 当成了协议的一部分了,一些开源框架肯定是根据这个协议开发的。
缺点:
Base64是可逆算法,Payload里面的信息是属于公开信息;
任何人拿到你的token在不过期的时间内都是可以访问的,所以我们的过期时间要注意酌情调整