什么是JWT
JWT是Json Web Token的全称,它是由三部分组成:
- header
- payload
- signature
header中通常来说由token的生成算法和类型组成。如:
[Python] 纯文本查看 复制代码
1
2
3
4
|
{
"alg" : "HS256" ,
"typ" : "JWT"
}
|
payload中则用来保存相关的状态信息。如用户id,role,name等。
[Python] 纯文本查看 复制代码
1
2
3
4
5
|
{
"id" : 10111000 ,
"role" : "admin" ,
"name" : "Leo"
}
|
signature部分由header,payload,secret_key三部分生成,其生成公式为:
[Python] 纯文本查看 复制代码
1
2
3
4
|
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret_key)
|
再将这三个部分组合成header.payload.signature的形式。
JWT如何工作首先用户发出登录请求,服务端根据用户的登录请求进行匹配,如果匹配成功,将相关的信息放入payload中,利用上述算法,加上服务端的密钥生成token,这里需要注意的是secret_key很重要,如果这个泄露的话,客户端就可以随意篡改发送的额外信息,它是信息完整性的保证。生成token后服务端将其返回给客户端,客户端可以在下次请求时,将token一起交给服务端,一般来说我们可以将其放在Authorization首部中,这样也就可以避免跨域问题。接下来,服务端根据token进行信息解析,再根据用户信息作出相应的操作。
JWT优点与缺点及对应的解决方案考虑JWT的实现,上面所述的关于session,cookies的缺点都不复存在了,不易被攻击者利用,安全性提高。利用Authorization首部传输token,无跨域问题。额外信息存储在客户端,服务端占用资源不多,也不存在session共享问题。感觉JWT优势很明显,但其仍然有一些缺点:
- 登录状态信息续签问题。比如设置token的有效期为一个小时,那么一个小时后,如果用户仍然在这个web应用上,这个时候当然不能指望用户再登录一次。目前可用的解决办法是在每次用户发出请求都返回一个新的token,前端再用这个新的token来替代旧的,这样每一次请求都会刷新token的有效期。但是这样,需要频繁的生成token。另外一种方案是判断还有多久这个token会过期,在token快要过期时,返回一个新的token。
- 用户主动注销,后台无法让用户强制下线。JWT并不支持用户主动退出登录,当然,可以在客户端删除这个token,但在别处使用的token仍然可以正常访问。为了支持注销和后台主动强制让用户下线, 解决方案是在注销时将该token加入黑名单。当用户发出请求后,如果该token在黑名单中,则阻止用户的后续操作,返回Invalid token错误。给名单的维护可以使用redis,token的过期时间和redis中数据的存活时间保持一致。