-
HTTP是无状态协议,浏览器的每一次请求,服务器都会独立处理,不与之前或之后的请求产生关联,所以,任何用户都可以通过浏览器访问服务器资源。而最典型的,一个用户登陆微博,发布、关注、评论,都应是在登录后的用户状态下的。为了维持前后请求,需要前端存储标记
-
cookie 是一种完善的标记方式,通过 HTTP 头或 js 操作,有对应的安全策略,是大多数状态管理方案的基石
-
session 是一种状态管理方案,前端通过 cookie 存储 id(session id),后端存储数据(redis库session id–session data),但后端要处理分布式问题
-
token 是另一种状态管理方案,相比于 session 不需要后端存储,数据全部存在前端,解放后端,释放灵活性
-
token 的编码技术,通常基于 base64,或增加加密算法防篡改,jwt 是一种成熟的编码方案
-
在复杂系统中,token 可通过 service token、refresh token 的分权,同时满足安全性和用户体验
-
session 和 token 的对比就是「用不用cookie」和「后端存不存」的对比
cookie 并不是客户端存储凭证的唯一方式。token 因为它的「无状态性」,有效期、使用限制都包在 token 内容里,对 cookie 的管理能力依赖较小,客户端存起来就显得更自由。但 web 应用的主流方式仍是放在 cookie 里,毕竟少操心。
狭义上,我们通常认为 session 是「种在 cookie 上、数据存在服务端」的认证方案,token 是「客户端存哪都行、数据存在 token 里」的认证方案。对 session 和 token 的对比本质上是「客户端存 cookie / 存别地儿」、「服务端存数据 / 不存数据」的对比。
- 「客户端存 cookie / 存别地儿」存 cookie 固然方便不操心,但问题也很明显:
1:在浏览器端,可以用 cookie(实际上 token 就常用 cookie),但出了浏览器端,没有 cookie 怎么办?
2:cookie 是浏览器在域下自动携带的,这就容易引发 CSRF 攻击
- 存别的地方,可以解决没有 cookie 的场景;通过参数等方式手动带,可以避免 CSRF 攻击。「服务端存数据 / 不存数据」
1:存数据:请求只需携带 id,可以大幅缩短认证字符串长度,减小请求体积
2:不存数据:不需要服务端整套的解决方案和分布式处理,降低硬件成本;避免查库带来的验证延迟
- 单点登录要求不同域下的系统「一次登录,全线通用」,通常由独立的 SSO 系统记录登录状态、下发 ticket(token),各业务系统配合存储和认证 ticket