一、JWT是什么
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.
这是官方文档的定义
翻译过来的意思就是JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地将信息作为JSON对象传输。 由于此信息是经过数字签名的,因此可以被验证和信任。 可以使用密钥(使用HMAC算法)或使用RSA或ECDSA的公用/专用密钥对JWT进行签名。
我对重点进行了加粗用于强调,加粗的会在后文进行详细阐述
二、JWT能做些什么?
常见的JWT用途分为两种:
1、授权
这是JWT最常用的方式,当用户登录后,这个用户之后的所有请求都将携带JWT,从而验证该用户是否被允许访问该服务、资源等。大部分单点登录功能都会使用JWT,因为他的开销小而且可以跨域。
2、信息交换
JWT可以很好的在多个服务之间进行信息交换,因为JWT可以通过签名确保该请求发起人是自己本人。
三、JWT认证与传统Session认证的对比
1、Session认证
a、Session认证方式
因为http是一种无状态协议,所以当用户向我们提供用户名和密码后,改状态无法保存,在下一次请求的时候还需要进行认证。所以为了让应用能够识别出发出请求的用户是谁时,我们需要在服务器存储用户登录的信息。然后在登录信息响应的时候传递给浏览器,使用cookie进行保存,以便下一次能够识别请求来自谁。
b、Seesion认证流程
c、Session认证的问题问题
- 1、sessionId是一个特征值,信息存储能力不够强,不容易拓展。
- 2、由于Session认证需要每个用户在认证后在服务端记录认证信息以方便分辨下一次请求的用户,并且Session通常是保存在内存中的,所以随着认证的用户增多,服务端的开销会也会变大。
- 3、由于用户认证的信息是保存在内存上,所以下一次用户请求时也必须请求同一台服务器才能得到授权,所以这种形式在分布式的应用上限制了负载均衡的能力,也限制了拓展了应用的能力。
- 4、由于是基于cookie进行识别的,所以如果cookie被截获,用户很容易受到跨站请求的伪造攻击。
- 5、如果系统是进行前后端分离的,那么会更糟糕。因为前后的分离会导致用户的一个请求需要转发多次。如果使用session,那么每次转发都需要携带sessionId到服务器,比如前端首先需要传递sessionId到nginx,然后nginx再携带sessionId到网关,最后网关还要携带seesionId到后端服务,如果该服务是集群部署,还需要实现session共享。
2、JWT认证
a、JWT认证流程
- 1、首先,前端将用户信息传递到到后端接口进行登录。如果信息验证成功,那么后端将会将用户的ID、用户名、权限等级等Payload和头部进行Base64编码拼接后签名形成JWT。
- 2、然后,如果登陆成功,后端将JWT返回给前端,前端可以将JWT保存在localStorage或者sessionStorage上,如果退出登录,删除保存的jwt即可。
- 3、接着,如果前端想要访问后端资源,需要将JWT存放在HTTP header中的Authorization位(以解决XSS和XSRF问题)。
- 4、如果后端接收到了前端的请求,会首先验证JWT的有效性,如:JWT是否过期、签名正确。
- 5、如果验证通过则后端使用payload存储中的用户信息进行操作。
b、JWT优势
JWT优势总结起来有四点:
- 1、简洁(Compact): 可以通过URL,POST参数或者在HTTP header发送,因为数据量小,传输速度也很快
- 2、自包含(Self-contained):负载中包含了所有用户所需要的信息,避免了多次查询数据库
- 3、因为Token是以JSON加密的形式保存在客户端的,所以JWT是跨语言的,原则上任何web形式都支持。
- 4、不需要在服务端保存会话信息,特别适用于分布式微服务。