token、session和cookie究竟是什么?
http是一个无状态协议
什么是无状态呢?
就是说这一次请求和上一次请求是没有任何关系的,互不认识,没有关联的。这种无状态的好处是快速。
cookie
cookie是存在浏览器的标识用户的方式,由服务端为每一个用户签发不用的session id发给浏览器存储在cookie中,下次访问会带上这个session id,服务端就知道这个访问是哪个用户了。
cookie面临的问题:
-
CSRF(跨站请求伪造)攻击,这个比较好解决,很多框架都屏蔽这个问题
-
有的客户端不支持cookie,需要手动设置,比如小程序
-
浏览器对cookie有限制,不能手动设置cookie,对于混合嵌套的开发有问题,比如小程序跳转H5页面,不能携带cookie
-
浏览器对单个cookie保存的数据不能超过4k,很多浏览器都限制一个站点很多保存20个cookie
session
session(会话),是存储在服务端标识用户的方式,服务端为每个用户生成不同的session id,还有与之相对应的信息,比如用户id和登录时间等。
session面临的问题:
-
负载均衡多服务器的情况,不好确认当前用户是否登录,因为多服务器不共享session。这个问题也可以将session存在一个服务器中来解决,但是就不能完全达到负载均衡的效果
-
每个客户端只需存储自己的session id,但是服务端却需要存储所有用户的session id,对服务器也是一个压力
注意:
-
cookie只是实现session的其中一种方案。虽然是最常用的,但不是唯一的方法。禁用cookie后还有其他方法存储,比如放在url中
-
现在大多都是session+cookie,但是只用session不用cookie,或是只用cookie不用session,在理论上都可以保持会话状态。可是实际中因为很多原因,一般不会单独使用
-
用session只需要在客户端保持一个id,实际上大量数据都是保存在服务端。如果全部用cookie,数据量大的时候客户端是没有那么多空间的
-
如果只用cookie不用session,那么账户信息全部保存在客户端,一旦被劫持,全部信息都会泄露。并且客户端数据量变大,网络传输的数据量也会变大
token
token也称作令牌,由uid+time+sign+【固定参数】
-
uid:用户唯一身份标识
-
time:当前时间的时间戳
-
sign:签名,使用hash/encrypt压缩成定长的十六进制字符串,以防止第三方恶意拼接
-
固定参数(可选):将一些常用的固定参数加入到token中是为了避免重复查库
token的认证方式类似于临时的整数签名,并且是一种服务端无状态的认证方式,非常使用与REST API的场景。
token在客户端一般存放于localStorage,cookie,或sessionStorage中。在服务器一般存于数据库中
总结
-
session存储与服务器,可以理解为一个状态列表,拥有一个唯一识别符号sessionId,通常存放于cookie中。服务器收到cookie后解析出sessionId,再去session列表中查找,才能找到响应的session。
-
cookie类似于一个令牌,装有sessionId,存储在客户端,浏览器通常会自动添加
-
token也类似于一个令牌,无状态,用户信息都被加密到token中,服务器收到token后解密就可知道是哪个用户,需要开发者手动添加