# Token、session、cookie
在讲Token之前,先简单说说什么是session和cookie。
首先要知道HTTP请求是无状态的,也就是不知道这一次的请求和上一次请求是否有关系,比如我们登录一个系统的时候,验证用户名密码之后,打开系统各个页面的时候就不需要再进行登录操作了,直到我们主动退出登录或超时退出登录;这里为了避免访问每个都登录一下,就要用到session、cookie。
cookie是在客户端(浏览器)保存用户信息的一种机制;而且每种浏览器存储大小会有一些差异,一般不超过4KB;
# session
session是在服务端保存,可以用于记录客户状态,比如我们经常会用session保存客户的基本信息、权限信息等;用户第一次登录之后,服务器就会创建一个session,浏览器再次访问时,只需要从该session中查找该客户的信息就可以了。
# session的原理
- (1)服务器在处理客户端请求过程中会创建session,并且为该session生存唯一的session ID。(这个session ID在随后的请求中会被用来重新获得已经创建的session。在session被创建后,就可以调用session相关的方法向session中新增内容,这些内容只会保存在服务器中)
- (2)服务器将session ID发送到客户端
- (3)当客户端再次请求时,就会带上这个session ID
- (4)服务器接收到请求之后就会一句Session ID 找到相应的Session ,完成请求
ps 1、虽然session保存在服务器,但它还是需要客户端浏览器的支持,因为session需要使用cookie作为识别标志。服务器会向客户端发送一个名为JSEDDIONID的cookie,它的值为session ID。 2、当cookie被禁用时,可以使用url重写的方法:将session写在URL中,服务器在进行解析。
# session的缺点
如果使用单个服务器的话,用户过多的话,会造成服务器开销太大。如果我们系统采用分布式的话,我们登录时,响应我们的那台机器会记录我们登录信息,万一下一个请求,响应我们的不是原来那台机器的话,它并没有存储我们之前会话信息,就会认为我们并没有登录。session粘连或者session复制都不是特别好的方案。
那既然服务端存储这些 SessionId 这么麻烦,人类又想出一招,那就是把这些SessionId 都存储在客户端。这个时候,cookie运用而生
# Token
但是这里会有个问题,服务器要保存所有用户的session信息,开销会很大,如果在分布式的架构下,就需要考虑session共享的问题,需要做额外的设计和开发,例如把session中的信息保存到Redis中进行共享;所以因为这个原因,有人考虑这些信息是否可以让客户端保存,可以保存到任何地方,并且保证其安全性,于是就有了Token。
Token是服务端生成的一串字符串,可以看做客户端进行请求的一个令牌。
当客户端第一次访问服务端,服务端会根据传过来的唯一标识userId,运用一些加密算法,生成一个Token,客户端下次请求时,只需要带上Token,服务器收到请求后,会验证这个Token。
有些公司会建设统一登录系统(单点登录),客户端先去这个系统获取Token,验证通过再拿着这些Token去访问其他系统;API Gateway也可以提供类似的功能,我们公司就是这样,客户端接入的时候,先向网关获取Token,验证通过了才能访问被授权的接口,并且一段时间后要重新或者Token。
# 基于Token的认证流程
整体的流程是这样的:
- 1、客户端使用用户名、密码做身份验证;
- 2、服务端收到请求后进行身份验证;(也可能是统一登录平台、网关)
- 3、验证成功后,服务端会签发一个Token返回给客户端;
- 4、客户端收到Token以后可以把它存储起来(可以放在);每次向服务端发送请求的时候,都要带着Token;
- 5、Token会有过期时间,过期后需要重新进行验证;
- 6、服务端收到请求,会验证客户端请求里面的Token,验证成功,才会响应客户端的请求。
# 总结
- cookie:保存在浏览器种,有大小限制,有状态;
- session:保存在服务器中,服务器有资源开销,分布式、跨系统不好实现;
- Token:客户端可以将Token保存到任何地方,无限制,无状态,利于分布式部署。
← 跨域方法原理详解 dns-Prefetch →