# Session-Cookie 鉴权

2022年8月31日7分钟阅读

- FormalSciences/ComputerScience
- ComputerSecurity/UserSecurity

## Session-Cookie 鉴权

Session-Cookie 认证是利用服务端的 Session（会话）和 浏览器（客户端） 的 Cookie 来实现的前后端通信认证模式。

在理解这句话之前我们先简单了解下什么是 Cookie以及什么是 Session ？

### Cookie 是什么

众所周知，HTTP 是无状态的协议（对于事务处理没有记忆能力，每次客户端和服务端会话完成时，服务端不会保存任何会话信息）；所以为了让服务器区分不同的客户端，就必须主动的去维护一个状态，这个状态用于告知服务端前后两个请求是否来自同一浏览器，而这个状态可以通过 Cookie 去实现。

#### 特点

- Cookie 存储在客户端，可随意篡改，不安全。

- 有大小限制，最大为 4kb。

- 有数量限制，一般一个浏览器对于一个网站只能存不超过 20 个 Cookie，浏览器一般只允许存放 300 个 Cookie。

- Android 和 IOS 对 Cookie 支持性不好。

- Cookie 是不可跨域的，但是一级域名和二级域名是允许共享使用的（靠的是 domain）。

### Session 是什么

Session 的抽象概念是会话，是无状态协议通信过程中，为了实现中断 / 继续操作，将用户和服务器之间的交互进行的一种抽象；具体来说，是服务器生成的一种 Session 结构，可以通过多种方式保存，如内存、数据库、文件等，大型网站一般有专门的 Session 服务器集群来保存用户会话；

#### 流程

1. 客户端： 用户向服务器首次发送请求。

2. 服务器： 接收到数据并自动为该用户创建特定的 Session / Session ID，来标识用户并跟踪用户当前的会话过程。

3. 客户端： 浏览器收到响应获取会话信息，并且会在下一次请求时带上 Session / Session ID。

4. 服务器： 服务器提取后会与本地保存的 Session ID 进行对比找到该特定用户的会话，进而获取会话状态。

5. 至此客户端与服务器的通信变成有状态的通信。

#### 特点

- Session 保存在服务器上。

- 通过服务器自带的加密协议进行。

### Session 与 Cookie 的差异

- 安全性： Cookie 由于保存在客户端，可随意篡改；Session 则不同存储在服务器端，无法伪造。所以 Session 的安全性更高。

- 存取值的类型不同： Cookie 只支持字符串数据；Session 可以存任意数据类型。

- 有效期不同： Cookie 可设置为长时间保持；Session 一般失效时间较短。

- 存储大小不同： Cookie 保存的数据不能超过 4K。

### Session-Cookie 的认证流程图

### Session-Cookie 认证步骤解析

1. 客户端： 向服务器发送登录信息用户名 / 密码来请求登录校验。

2. 服务器： 验证登录的信息，验证通过后自动创建 Session（将 Session 保存在内存中，也可以保存在 Redis 中），然后给这个 Session 生成一个唯一的标识字符串会话身份凭证 session_id（通常称为 sid），并在响应头 Set-Cookie 中设置这个唯一标识符。

   > 注：可以使用签名对 sid 进行加密处理，服务端会根据对应的 secret 密钥进行解密 （非必须步骤）

3. 客户端： 收到服务器的响应后会解析响应头，并自动将 sid 保存在本地 Cookie 中，浏览器在下次 HTTP 请求时请求头会自动附带上该域名下的 Cookie 信息。

4. 服务器： 接收客户端请求时会去解析请求头 Cookie 中的 sid，然后根据这个 sid 去找服务端保存的该客户端的 sid，然后判断该请求是否合法。

### Session-Cookie 的优点

- Cookie 简单易用。

- Session 数据存储在服务端，相较于 JWT 方便进行管理，也就是当用户登录和主动注销，只需要添加删除对应的 Session 就可以了，方便管理。

- 只需要后端操作即可，前端可以无感等进行操作。

### Session-Cookie 的缺点

- 依赖 Cookie，一旦用户在浏览器端禁用 Cookie，那么就 GG 思密达了。

- 非常不安全，Cookie 将数据暴露在浏览器中，增加了数据被盗的风险（容易被 CSRF 等攻击）。

- Session 存储在服务端，增大了服务端的开销，用户量大的时候会大大降低服务器性能。

- 对移动端的支持性不友好。

### 使用场景

- 一般中大型的网站都适用（除了 APP 移动端）。

- 由于一般的 Session 需集中存储在内存服务器上（如 Redis），这样就会增加服务器的预算，所以预算不够请谨慎选择。