JWT的优缺点分析

今天主要看了一下JWT方面的知识,这里通过一篇小记分析JWT在实际应用中的优缺点。

JWT又称Json Web Token,在实际应用中被用于鉴权,是一种新型的、不使用Session、用户鉴权数据存放在客户端并由客户端管理、服务端只负责校验的方式。

JWT的组成

JWT的组成分成三部分,分别是头部(Header)、载荷(Payload)以及签名(Signature)。

头部存放的是这个Token的基本信息,包括这个Token的类型和Token所用的加密算法。头部通过简单的base64加密构成JWT的第一部分。

Payload是存放Token有效信息的地方,其中官方提供了可选字段:

  • iss:签发人
  • exp:过期时间
  • sub:主题
  • aud:受众
  • nbf:生效时间
  • iat:签发时间
  • jti:编号

除了这些字段,你也可以自定义自己的字段放在Payload部分。需要注意的是Payload部分默认也是不加密的,只经过一次base64转换,Payload部分适合防止客户端可以合法获取到的信息,不能放敏感信息在里面,对于客户端来说,这一部分其实等同于明文。

Signature是JWT最最重要的地方,因为JWT是存放在客户端的,所以它是完全可以被篡改的,Signature这一部分就是为了防止JWT被篡改而加入的,它会利用Header内指定的算法,通过一个密钥对整个Token进行HMAC SHA256计算,得到一个校验值。

这个校验值可以供服务器检验JWT是否有效。从算法上来说,当密钥不是很复杂的时候,Signature是可以被暴力破解出来的,会给服务带来安全问题,像hashcat就有爆破JWT密钥的能力。

如果要使用JWT,这个密钥一定要尽可能有很高的随机性、很高的强度来避免破解的问题。

参考:
jwt.io

使用

JWT的使用很简单,服务器把JWT放到回复的任何地方给客户端,客户端拿到JWT之后可以把它存储起来。

在客户端向服务端发送请求的时候,把Token在请求头带上,服务器做好对应的解析,就能实现一个身份认证的操作。

原则上JWT是可以放到任何地方的,只要能发到服务端就行,但是各种以来、框架有约定俗成的做法,这个做法可以规避掉跨域等问题,一般是这么用的:

1
Authorization: Bearer <token>

这样把Token附在请求头里就行了。

利弊

应用JSON Web Token可以解决很多问题,比如跨服务调用,有的时候A、B、C、D...等系统用的是同一个系统,如果用Session的话想要让他们共用一个身份验证体系,就是一个大工程了,JWT则能很好地解决这个问题。

而且它在不同语言编写的不同系统中也具有通用性,移动端App很多时候用Session不是一个好选择,但是用JSON Web Token则可以让客户端更好地保持登录状态。

一般来说,在应用了JSON Web Token之后,所有需要权限验证的请求都需要带上这个Token,前后端设计得当的情况下,应用JWT之后可以不再另外做CSRF的防护。

最重要的一个特性是,JWT能够允许服务器不持有任何的状态,减少服务器的资源。

同样,由于服务器不持有JWT了,这也导致了JWT的一个大问题 —— 不能被主动废弃。Session在用户登出之后就会立刻被服务器销毁,立刻失效,但JWT在过期时间未到的情况下仍然是有效的,这一点服务端只能够通过特别的设置去拒绝已经被认为无效的Token。

JWT还有一个问题在于它需要保鲜,每隔一段时间客户端就需要请求服务端获取新的Token,对Token进行刷新,对于一个应用来说这会增加一些麻烦。

除此之外,安全问题也是很重要的问题,有的人说JWT安全,也有的人说不安全,JWT本身使用得当是安全的,但是它太过于依赖密钥,总体安全性会不如Session。

带宽消耗也是JWT的一个问题,JWT内容过多的时候会造成所有的请求都携带比使用Session过多的数据,对于并发量很高的应用来说这不是好事。

其他参考

《JWT也是不是万能的呀,入坑需谨慎》
《JSON Web Token入门教程》