文章目录
- HTTP
- Cookie
- Session
- Session认证流程
- Session 共享方案
- Token
- Token认证流程
- JWT
- JWT认证流程
HTTP
HTTP 本质上是无状态的,每个请求都是互相独立、毫无关联的,协议不要求客户端或服务器记录请求相关的信息。服务端无法确认当前访问者的身份信息,无法分辨上一次的请求发送者和这一次的发送者是不是同一个人。所以服务器与浏览器为了进行会话跟踪,就主动的去维护了一个状态,这个状态用于告知服务端前后两个请求是否来自同一浏览器,而这个状态需要通过 cookie 和 session 去实现。
- 更多HTTP相关的知识:
- HTTP协议之基础篇
Cookie
- Cookie 存储在客户端,Cookie是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。
- Cookie是不可跨域的: 每个 Cookie 都会绑定单一的域名,无法在别的域名下获取使用,一级域名和二级域名之间是允许共享使用的(靠的是 domain)。
- Cookie存在安全隐患,通过拦截或本地文件找到你的Cookie可以进行攻击。
- Cookie 有大小限制(不能超过4K)以及浏览器也可能存在对Cookie的个数限制(一般最多保存20个cookie)。
- 移动端对 Cookie 的支持不是很好。
Session
- Session 是客户端与服务端维持的一个有状态会话。
- Session 是常见的基于Cookie 实现的,也可以基于传输时用body来传输Session来实现。
- Session 存储在服务器端,SessionId 会被存储到客户端的Cookie 中,也可以存储在LocalStorage(浏览器)。
- Session 能够有效管理用户登录的状态:续期、销毁等。
- 当网站采用集群部署的时候,会遇到多台 web 服务器之间如何做 Session 共享的问题。
- 服务端需要存储Session数据,当用户同时在线量比较多时,服务端内存压力也大。
Session认证流程
- 用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建对应的Session并存储。
- 请求返回时将此 Session 的唯一标识信息 SessionId 返回给浏览器
- 浏览器接收到服务器返回的 SessionId 信息后,会将此信息存入到 Cookie 中,同时 Cookie 记录此 SessionId 属于哪个域名。
- 当用户第二次访问服务器的时候,请求会自动判断此域名下是否存在 Cookie 信息:
- 如果存在自动将 Cookie 信息也发送给服务端,服务端会从 Cookie 中获取 SessionId,再根据 SessionId查找对应的 Session 信息。
- 如果没有找到说明用户没有登录或者登录失效如果找到 Session 证明用户已经登录可执行后面操作。
以上的Session认证实现是基于Cookie的。假如浏览器禁止 Cookie或不支持 Cookie。一般会把 SessionId 跟在 url 参数后面即重写 url,所以 Session 不一定非得需要靠 Cookie实现。
Session 共享方案
Session复制
- 任何一个服务器上的 session 发生改变(增删改),该节点会把这个 session 的所有内容序列化,然后广播给所有其它节点,不管其他服务器需不需要 session ,以此来保证 session 同步
- 优点: 可容错,各个服务器间 session 能够实时响应。
- 缺点: 会对网络负荷造成一定压力,如果 session 量大的话可能会造成网络堵塞,拖慢服务器性能。
粘性 Session /IP 绑定策略
- 采用 Ngnix 中的 ip_hash 机制,将某个 ip的所有请求都定向到同一台服务器上,即将用户与服务器绑定。
- 优点: 简单,不需要对 session 做任何处理。
- 缺点: 缺乏容错性,如果当前访问的服务器发生故障,用户被转移到第二个服务器上时,他的 session 信息都将失效。
Session 共享
- 使用分布式缓存方案,比如Redis 来缓存 Session。
- 把 session 放到 Redis 中存储,虽然架构上变得复杂,并且需要多访问一次 Redis ,但是这种方案带来的好处也是很大的:
- 实现了 session 共享,可以水平扩展。
- 服务器重启 session 不丢失(不过也要注意 session 在 Redis 中的刷新/失效机制)。
- 不仅可以跨服务器 session 共享,甚至可以跨平台。
Session 持久化
- 将 session 存储到数据库中,保证 session 的持久化。
- 优点: 服务器出现问题,session 不会丢失。
- 缺点: 如果网站的访问量很大,把 session 存储到数据库中,会对数据库造成很大压力,还需要增加额外的开销维护数据库。
Token
- 访问资源接口(API)时所需要的资源凭证
- 简单Token的组成: 无意义的一串随机字符串。
- 特点:
- 服务端无状态化、可扩展性好
- 支持移动端设备
- 安全
- 支持跨程序调用
Token认证流程
- 客户端使用用户名和密码请求登录;服务端收到请求,去验证用户名与密码。(
也可以使用短信验证码,邮箱等方式登录
) - 验证成功后,服务端会签发一个Token并存储,然后把这个Token发送给客户端。
- 客户端收到 Token以后,会把它存储起来 (Cookie 或者 LocalStorage) 。
- 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token。
- 服务端收到请求,然后拿着服务端存储的Token去验证客户端请求里面带着的Token,如果验证成功,就向客户端返回请求的数据。
普通Token其实就是照着SessionId的思路实现的。这样就不依赖于Cookie或者Session了。
JWT
- JSON Web Token(简称 JWT)是目前最流行的跨域认证解决方案。
- JWT 是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准。
- JWT 的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。
- 可以使用 HMAC 算法或者是 RSA 的公/私秘钥对 JWT 进行签名。因为数字签名的存在,这些传递的信息是可信的。
- 可以将JWT当作一种特殊的Token,Token中会携带用户的很多信息。
JWT认证流程
- 客户端使用用户名和密码请求登录;服务端收到请求,去验证用户名与密码。(
也可以使用短信验证码,邮箱等方式登录
) - 验证成功后,服务端会通过自己加密算法签发一个Token(服务端不存储),这个Token中会携带很多用户信息等其他信息,然后把这个Token发送给客户端。
- 客户端收到 Token以后,会把它存储起来 (Cookie 或者 LocalStorage) 。
- 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token。
- 服务端收到请求,然后服务端会解密客户端请求里面带着的Token,如果验证成功,就向客户端返回请求的数据。
普通Token和JWT的区别:服务端验证客户端发来的token信息要进行数据的查询操作;JWT验证客户端发来的token信息就不用, 在服务端使用密钥校验就可以,不用数据的查询。
- 每种方案各有优缺点,选择适合业务的方案就可以。
你知道的越多,你不知道的越多。