分析 Cookie、Session、Token
一、cookie、session
首先介绍一下 cookie 和 session,我们要知道没有 cookie 和 session 会是什么样的,为什么需要 cookie 和 session 呢?
场景:在线购物网站
-
不使用 session 和 cookie 的情况
- 用户访问网站,每次操作都需要重新登录或者是提供身份信息
- 用户浏览商品,将商品添加到购物车,购物车的信息可能需要保存在 url 或者前端存储中,比较麻烦
- 用户切换页面或者关闭浏览器重新打开之前的购物车信息都丢失了,用户需要重新添加商品到购物车
- 结账时需要重新提供所有必要的信息
-
使用 session 和 cookie 的情况
- 用户登录网站,服务器创建 session,生成 sessionID
- sessionID 通过 cookie 发生给浏览器
- 用户浏览商品,将商品添加到购物车,购物车信息存储在服务器的 session 中
- 用户切换页面或者关闭浏览器重新打开后
- 浏览器发送包含 sessionID 的 cookie
- 服务器识别到了用户,回复的购物车状态
- 用户可以继续购物或结账了
在这个场景中,不适用 session 和 cookie 会导致:
- 用户体验变差(需要频繁的登录,购物车状态不会保存)
- 开发难度增加(需要另找方式存储和传递状态信息)
- 安全性降低(可能需要在不安全的地方存储敏感信息)
简单来说就是,如果不使用 cookie 和 session 的话,那么现在这个网站就是一个无状态的网站,保留不了用户的信息,除非每一次被动的进行身份验证,并且无法知道用户之前的操作是怎么样的,进行身份验证后才能从数据库中拿到该用户之前的购物车信息
现在我们明白了想要让用户体验性变好,安全性提升和降低开发难度的话就需要这种自动的身份验证的方式,那么问题又来了既然有了 cookie,为什么还需要 session 呢,以及我们该如何选择?
首先我先介绍一下它们的共同点:
-
用户管理状态:
- 两者都是用于管理用户的状态和会话记录的,帮助服务器识别用户
-
HTTP 协议:
- 都是基于 HTTP 协议的机制,允许客户端和服务器之间传递信息
-
存储信息:
- 都可以存储用户相关的信息,如用户 id、偏好设置等
-
生命周期:
- 都可以设置过期时间,决定何时失效
不同点:
场景:在线购物网站(使用 session或cookie 和两者都使用的的情况)
- 只是用 session:
- 用户登录网站,服务器创建 session,生成 sessionID
- sessionID 通过 URL 参数或者自定义头部返回
- 用户添加商品到购物车,每次请求都需要传递 sessionID,信息存储在 session 中(session 是存储在服务器的数据结构)
- 如果用户关闭浏览器,session 信息可能丢失
特点:
- 安全新较高,敏感数据存储在服务器
- 需要在每个请求中手动传递 sessionID
- 用户体验可能不佳,因为 url 可能变得很长或需要额外的请求头
session 的存储过程
- 用户添加商品到购物车
- 客户端发送请求到服务器(包含商品信息和 session ID)
- 服务器根据 session ID 找到对应的 session
- 服务器将商品信息添加到该 session 中
- 只使用 cookie:
- 用户登录网站
- 用户信息和购物车数据(特殊情况)直接存储在 cookie 中
- 每次请求自动发送 cookie
- 用户添加商品到购物车,直接更新 cookie
- 即使关闭浏览器,信息也能保留(取决余 cookie 设置)
特点:
- 实现简单,不需要服务器端存储数据
- 安全性较低,敏感数据存储在客户端
- 数据存储受限于 cookie 大小限制
- 每次请求都会发送全部 cookie 数据,可能影响性能
- 结合使用
特点:
- 结合了两者的优化:cookie 的便利性和 session 的安全性
- 敏感数据存储在服务器,只有 sessionID 在客户端
- 用户体验好,无需手动管理 sessionID
- 服务器需要存储 session 数据,可能影响扩展性
总结:
- 只用 session:安全性高,单用户体验可能受影响
- 只用 cookie:实现简单,但安全性和存储容量有限
- session+cookie:平衡了安全性和用户体验,是最常见的选择
OK,既然是这样的话,我们就可以排除一个选项了,那么现在我们只需要在 session+cookie 或者 jwt(token)中选出一种即可。
二、token
那么下面我们就来再说一下 token 是一个什么样的情况,以及它和 session+cookie 是否是同一种概念,该如何选择?
1. 什么是 token?
token 是一种用于身份验证和授权的字符串,通常用于用户登录后由服务器生成并返回给客户端。token 可以包含用户的身份信息和权限信息。token 的主要作用就是让服务器能够识别用户的身份,而无需在每次请求中传递敏感信息
与 seesion+cookie 的共同点:
- 身份验证:
- 两者都用于身份验证和授权,帮助服务器识别用户身份。
- 信息传递:
- 都允许在客户端和服务器之间传递用户相关的信息。
- 过期机制:
- 都可以设置过期时间,决定何时失效,以增强安全性。
- HTTP 协议:
- 都是基于 HTTP 协议的机制,允许在请求和响应中传递信息。
区别:
| 特性 | Token | Session + Cookie |
|---|---|---|
| 存储位置 | 存储在客户端(如 localStorage、sessionStorage 或 cookie) | 存储在服务器端(session)和客户端(cookie) |
| 状态管理 | 无状态 | 有状态 |
| 安全性 | 需要额外的安全措施(如 HTTPS) | 敏感数据存储在服务器,安全性较高 |
| 跨域支持 | 支持跨域 | 受同源策略限制 |
| 撤销机制 | 无法撤销,直到过期 | 可以随时使 session 失效 |
| 适用场景 | 适合 API、单页应用(SPA)和微服务架构 | 适合传统的服务器端渲染应用 |
| 数据大小 | 通常比 session ID 大 | session ID 较小,存储在 cookie 中 |
| 实现复杂性 | 需要处理 Token 的生成、解析和验证 | 需要管理 session 的生命周期和存储 |
2. token 的优点:
- 无状态:token 是自包含的,服务器不需要存储会话信息,适合分布式系统和微服务架构
- 跨域支持: token 可以在不同的的域之间传递,适合现代 Web 应用和 API
- 灵活性: token 可以包含用户的权限信息,便于进行颗粒度的访问
- 易扩展:由于不依赖与服务器,token 更适合高并发场景
3. token 的缺点:
- 安全性问题:token 一旦生成,知道过期都无法撤销,可能导致安全隐患
- 储存问题:如果存储在 localStorage 中,可能会受到 xss 攻击的影响
- 数据大小:token 通常比 sessionID 大,可能会影响网络传输性能
其实这些缺点,我觉得是无足轻重的,问题不大
4. token 的工作流程
- 用户登录网站,提供凭据(如用户名和密码)。
- 服务器验证凭据,如果有效,生成一个 Token(如 JWT)。
- 服务器将 Token 返回给客户端,客户端可以将其存储在 localStorage、sessionStorage 或 cookie 中。
- 客户端在后续请求中将 Token 作为请求头(如 Authorization)发送给服务器。
- 服务器验证 Token 的有效性,识别用户身份,并处理请求。
5. 该如何选择?
选择 token 还是 session+cookie 主要取决于以下几个因素:
应用类型:
- 对于单页面和移动应应用,token 更加灵活和合适
- 对于传统的服务器渲染,Session+Cookie 可能更为简单和安全
安全需求:
- 如果需要更高的安全性和控制,Session+Cookie 是更好的选择
- 如果需要支持跨域请求,token 是更合适的选择
扩展性
- 对于高并发和分布式的系统,token 提供了更好的扩展性
- 对于小型的应用,session+cookie 的实现可能更简单
总之,Token 提供了一种灵活、无状态的身份验证机制,适合现代 Web 应用和 API。与传统的 Session + Cookie 机制相比,Token 在跨域支持和扩展性方面具有优势,但在安全性和撤销机制上需要额外的考虑。根据具体的应用需求和架构选择合适的身份验证方式是至关重要的。
所以该选择哪一种方式进行身份验证,这下心里有谱了吧。