Cookie,Session和Token
为什么需要Cookie
Http是无状态的协议(对于事物处理没有记忆能力,每次客户端和服务端会话完成时,服务端不保存任何会话信息);每个请求都是完全独立的,服务端无法确认当前访问者的身份信息,无法分辨上一次的请求发送者和这一次的发送者是不是同一个人。所以服务器与浏览器为了进行会话跟踪,就必须主动的去维护一个状态。而这个状态需要通过cookie或者session去实现。
cookie存储在客户端:cookie时服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。
cookie是不可跨域的:每个cookie都会绑定单一的域名,无法在别的域名下获取使用,一级域名和二级域名是允许共享使用的(靠的是domain)。
什么是Session
session是另外一种记录服务器和客户端会话状态的机制
session是基于cookie实现的,session存储在服务器端,sessionId会被存储到客户端的cookie中
微信图片_20200528160217.jpg
session的认证流程:
- 用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建对应的Session
- 请求返回时将此Session的唯一标识信息SessionID返回给浏览器
- 浏览器接收到服务器返回的SessionID信息后,会将此信息存入到Cookie中,同时Cookie记录此SessionID属于哪个域名
- 当用户第二次访问服务器的时候,请求会自动判断此域名下是否存在Cookie信息,如果存在自动将Cookie信息也发送到服务端,服务端会从Cookie中获取SessionID,在根据SessionID查找对应的Session信息,如果没有找到说明用户没有登录或者登录失效,如果找到Session证明用户已经登录可执行后面操作。
根据以上流程可知,SessionID是连接Cookie和Session的一道桥梁,大部分系统也是根据此原理来验证用户登录状态 。
Cookie和Session的区别
- 安全性:Session比Cookie安全,Session是存储在服务器端的,Cookie是存储在客户端的。
- 存取值的类型不同:Cookie只支持存字符串数据,想要设置其他类型的数据,需要将其转换成字符串,Session可以存任意数据类型.
- 有效期不同:Cookie可设置为长时间保持。比如我们经常使用的默认登录功能,Session一般失效时间较短,客户端关闭或者session超时都会失效
- 存储大小不同:单个Cookie保存的数据不能超过4K,Session可存储数据远高于Cookie,但是当访问量过多,会占用过多的服务器资源.
什么是Token
AccessToken
- 访问资源接口API时所需要的资源凭证
- 简单token的组成:uid,time,sign,token的前几位以哈希算法压缩成的一定长度的十六进制字符串
特点: - 服务端无状态化,可扩展性好
- 支持移动端设备
- 安全
- 支持跨程序调用
token的身份验证流程:
1.客户端使用用户名跟密码请求登录
2.服务端接收到请求,去验证用户名和密码c
3.验证成功后,服务端会签发一个token并把这个token发送给客户端
4.客户端接收到token以后,会把它存储起来,比如放在cookie里或者LocalStorage里
5.客户端每次向服务端请求资源的时候会带着服务端签发的token
6.服务端收到请求,然后去验证客户端请求里面带着的token,如果验证成功,就向客户端返回请求的数据
每一次请求都需要携带token,需要把token放到HTTP的Header里
基于token的用户认证时一种服务端无状态的验证方式,服务端不存放token数据,用解析token的计算时间换取session的存储空间,从而减轻服务器的压力,减少频繁的查询数据库。
分布式架构下 session 共享方案
1.Session赋值
任何一个服务器上的session发生改变,该节点会把这个session的所有内容序列化,然后广播给所有其他节点,不管其他服务器需不需要session,以此来保证session同步。
优点:可容错,各个服务器间session能够实时响应
缺点:会对网络负荷造成一定的压力,如果session量大的话可能会造成网络堵塞
2.粘性session/IP绑定策略
采用Ngnix中的ip_hash机制,将某个ip的所有请求都定向到同一台服务器上,即将用户与服务器绑定。用户第一次请求时,负载均衡器会将用户的每次请求转发到A服务器上,如果负载均衡器设置了粘性session的话,那么用户以后的每次请求都会转发到A服务器上,相当于把用户和A服务器粘到了一块,这就是粘性session机制。
优点:简单,不需要对session做任何处理
缺点:缺乏容错性,如果当前访问的服务器发生故障,用户被转移到第二个服务器上时,它的session信息都将失效。
3.Session共享
使用分布式缓存方案比如Memcached,Redis来缓存session,但是要求Memcached或Redis必须是集群。
把session放到Redis中存储,虽然架构上变的复杂,并且需要多访问一次Redis,但是这种方案带来的好处也是很大的:
实现了Session共享
可以水平扩展(增加Redis服务器)
服务器重启session不丢失
不仅可以跨服务器session共享,甚至可以跨平台(例如网页端和App端)