JWT基础原理
整理自https://www.v2ex.com/t/656457 和http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html
狭义的Session和Cookie
普通的用户认证流程通常如下:
- 客户端向服务端发送用户名和密码。
- 服务端验证通过后,在当前对话(session)里面保存相关数据(session data),比如用户角色、登录时间等。
- 服务端向用户返回一个session_id,写入用户本地的Cookie。
- 客户端随后的每一次请求,都会自动将Cookie加到请求头中,其中的session_id被传回到服务端。
- 服务端收到session_id后,检索session data找到用户相关信息。
这种模式的扩展性不好,对于服务器集群,或者是跨域的服务架构等要求session数据共享的情况,一种解决方案是session数据持久化,写入数据库,这种方案的优点是架构清晰,缺点是工程量比较大,而且要性能有一定的损耗。另一种方案是服务器不保存session数据,采用Client Side Session的模式,所有数据都保存在客户端,每次请求再发回服务器。JWT就是这种方案的一个代表。
JWT
JWT原理
JWT全称是Json Web Token,它的原理是,在服务器认证以后,生成一个JSON对象,返回给用户,例如
{
"username": "zhangsan",
"role": "admin",
"expiredTime": "20180701000000"
}
之后,用户与服务端通信的时候,都要带上这个JSON对象。而服务器就不保存任何session数据了,也就是说,服务器变成无状态了,从而比较容易实现扩展。
服务器只靠这个对象来认定用户身份。因此为了防止用户篡改数据,服务器在生成这个对象的时候,需要加上签名。
JWT 的数据结构
JWT是一个很长的字符串,中间用点分隔成三个部分,分别是Header,Payload和Signature。
其中Header是一个 JSON 对象,描述JWT的元数据,例如
{
"alg": "HS256",
"typ": "JWT"
}
其中alg属性表示签名算法,默认是HMAC SHA256。typ属性表示令牌类型,JWT令牌统一写为JWT。
Payload也是一个 SON 对象,用来存放实际传递的数据。JWT规定了7个官方字段。
- iss (issuer):签发人
- exp (expiration time):过期时间
- sub (subject):主题
- aud (audience):受众
- nbf (Not Before):生效时间
- iat (Issued At):签发时间
- jti (JWT ID):编号
除了官方字段,也可以定义私有字段
注意,JWT默认是不加密的(只是签名),任何人都可以读到,不要把私密信息放在这个部分。
这两部分都通过Base64URL算法转成字符串。
Signature部分是通过服务端的私钥,根据Header中指定的签名算法,对前两部分进行签名,防止数据篡改。
然后把Header,Payload,Signature三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,返回给用户。
JWT的使用方式
客户端收到服务器返回的Token,可以储存在Cookie里,也可以储存在localStorage里。
此后,客户端每次与服务器通信,都要带上这个Token。为了方便跨域,通常更好的做法是放在HTTP请求头的Authorization字段里面,或者放在POST请求的数据体里面。
JWT的特点
- JWT默认不加密,但也是可以加密的。在生成原始 Token 以后,可以用密钥再加密一次。
- JWT的最大缺点是,由于服务器不保存session状态,因此无法在使用过程中使某个token失效,除非服务器部署额外的逻辑。
广义的Session和Cookie
广义的Session指的就是从用户登录到登出的过程中,维持的这样一种状态和相关信息。
Sever Side Session
Sever Side Session是最常见的 Session实现,但它并不是唯一的一种Session实现。
优点:
- 数据存储在服务端,相对安全性更强
- 请求时只需要传递Session-ID,减小流量开销
- 可以方便的管理和吊销Session
缺点:
- Session-Data集中管理,不利于分布式架构,需要专门解决Session共享问题
- Session-Data需要占用服务端内存/存储,对服务端存在压力
Client Side Session
Client Side Session顾名思义是在客户端存储Session。
优点:
- 将存储压力转移到了客户端,可以减小服务端的资源消耗
- 分布式架构下,不需要考虑Session共享问题
劣势:
- Cookie默认有4KB限制,不能存储太多内容
- 存在重放攻击的风险,客户端可能会将数据替换为合法的旧数据
- 实现Session数据的拉黑、强制失效等功能时比较复杂
- 部分实现没有对数据进行加密,客户端可以直接查看到数据内容,存在安全风险
相关问题
Token是什么?
Token实际上泛指用于认证鉴权的凭据,广义上来说,如果使用Session-ID或Session-Data进行用户认证,也可以称之为Token。
Session和JWT的关系是什么?
JWT是特定的一种Token生成方式,它有特定的格式,通过签名保证了信息的不可篡改,可以作为Client Side Session的数据处理方式。