HTTP无状态协议
Http协议是一t种无状态协议,协议对于交互的场景没有扩展功能。无状态有一系列的好处:
- 可以将请求发送到集群中的任意一点点进行处理,方便实现负载均衡等。
- 无状态意味着服务端不要保存用户的状态的状态信息,能够节约大量的资源,有利于高并发
但是有些时候是需要保存状态信息的,比如说请求资源的时候,需要保存用户的登录信息;
基于cookies
cookies只能携带4kb的数据,且不支持跨域请求,用户信息存储在客户端,容易被第三方获取,另外还有csrf风险;
基于sessionID
认证完成后,客户端持有sessionId,服务端保存session信息,通过客户端传过来的sessionId获取用户信息
- 因为session信息保存在服务端,如果用户量特别大的时候,大量的session信息会占用大量的内存
- 因为服务器只保存了自己生成的session信息,在分布式场景下无法共享
- 服务器重启时,经由该服务器保存的session会全部失效,需要重新登录
对于以上,可以通过将session存入redis来解决内存占用、分布式认证、以及服务重启导致session失效的问题
基于token
- token是服务端根据用户信息生成的一串字符串,以作为客户端进行请求的一个凭证;
- 当用户第一次登录后,服务器变生成一个token给客户端,以后客户端请求资源时,每次只需要将token带上就行;
token相比session的区别在于:
- token可以不用保存在服务端,服务端只要保存一个密钥,每次对客户端请求带来token进行验证即可;
- sessionID在请求时,浏览器会默认携带,而token需要通过代码携带;
基于JWT
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。
由此可见,JWT是token的一种,只是规定了token的格式,JWT有header(头)、playload(载荷)、signature(签名)三部分组成(xxx.yyyy.zzz的格式);JWT各部分的详细介绍参考
- 客户端持有JWT令牌,服务端只需要持有一个密钥,即可通过签名验证客户端的JWT是否有效,以及从因此服务端不要存储任何信息,也不要需要查询数据库;
- JWT一旦有服务端签发之后,便会在有效期内一直有效(有效期在载荷中设置),无法踢出用户用户的登录状态,即使服务端重新启动,JWT只要在有效期内,也同样是有效的;
- JWT一旦签发,也无法主动控制JWT的失效时间(比如想每次请求完成之后,刷新JWT的失效时间);
对于2、3中的JWT的失效时间,可以将JWT的有效时间设置为永久,并将其保存在redis中,由redis做JWT的踢出以及JWT的失效时间控制;