大家好 我是耗子
现代应用大都是前后端分离开发, 前端(客户端)负责与用户交互, 后端(服务器)进行数据请求, 回复前端的请求, 双端通过 HTTP协议
进行数据传输。
但是 HTTP协议
属于无状态协议, 每一次服务器访问都不相关, 客户端也不会记得每一次访问的内容,
试想一下, 双11你登陆账号, 准备购物。但是每打开一个新的页面, 服务器都不曾记得你登陆过, 你需要重新登陆, 用户体验得有点多差。
所以这就有了可持续化访问的出现, 本质上指的就是 通过外部存储使得访问 状态化, 常见方案有:
Session
存储Token
存储Credentials
授权
这三种方案其实本质上都是基于 Cookie 实现的, 这里的 Cookie
指的是 浏览器Cookie, 用于存储少量用户信息, 附带在客户端的请求报文中, 当服务器收到请求, 就可以读取请求报文中的 Cookie
, 由此达到状态访问的目的。
这其实就是最简单的 Session
会话, 在早期的网络应用中, 这种方式非常常见, 但是问题也显而易见, 用户可以查看和篡改 Cookie
, 不安全。
Session
Session
指的是客户端与服务器之间访问产生的会话, 用来存储交互信息, 早期 Session
普遍由服务器存储在 Cookie
中回复给客户端, 客户端又携带 Cookie
访问服务器。这被称之为 客户端 Session
。
但正如之前所说, 用户可以查看和篡改 Cookie
中的内容, 所以衍生出了 服务器 Session
, 我们常说的 Session
指的其实也是 服务器 Session
。
服务器 Session 指的就是在后端数据库中存储 用户相关信息, 在 Cookie
中存储一个 session_id
返回给客户端, session_id
也是一种早期的 token
令牌。
客户端每次请求中携带 Cookie
, 服务器识别 Cookie
并通过其中的 session_id
访问数据库中的相应数据, 从而到达可持续化访问的目的。
Session 的优点
这里指的依旧是 服务器 Session
, 相较于 传统 Cookie
也就是 客户端 Session
:
- 安全性高: 信息存储在服务器, 不易篡改。
- 可以存储较大信息: Cookie 本身仅支持 4Kb 以下, 而 Session 存储于服务器, 依靠于数据库, 容量不限。
- 存储类型多样: Cookie 只允许字符串类型, 而 Session 允许任意类型。
- 可控性高: Cookie 本身只能设置固定有效时间, 而 Session 存储于服务器, 可以适应多种场景, 有效进行管理。
- 删除非法 Session
- 过期自动清理 Session
- 刷新有效时间等
Session 的缺点
Session 并不是完美的, 在不同的场景下也会暴露它的各方面不足。
-
服务器存在负担: 随着用户量的增大, 每个用户都存储交互信息在服务器, 势必造成服务器负担。
-
Session
依靠HTTPS
安全访问: 在不安全的网络环境下, Cookie 会被盗用, 意味着 SessionId 会被盗用 -
Sesion_ID
盗用风险: 正如上一点所说, 其实session_ID
就是早期的token
, 一旦被盗用就会导致非法用户盗用Session
当然, 可以通过在服务器存储用户访问的IP地址和代理信息来保障, 但这样会导致
Session
增大, 且用户可能需要频繁登陆。 -
不可跨域: 这是由于 Cookie 不可跨域导致, 不同域名需要不同验证
-
不可共享: 在多集群服务器的情况下, A服务器和B服务器 Session 不共享, 需要而外进行配置
-
CSRS攻击: 如果网站存在恶意脚本比如
http://www.bank.com/api/transfer?count=1000&to=Tom
, 这种脚本存储在一段文本甚至是一张图片中, 如果我们使用Session
的方式, 当我们点击图片就会导致触发。
Token 存储
Token
指的是令牌, 它是一种跨域认证方案, 最常见的 token
方案就是 jwt
, 它与 客户端 Session
的过程类似:
- 如果用户登录成功,服务器返回一个
Token
给客户端。 - 客户端保存
Token
在客户端的localStorage
,sessionStorage
,cookie(不推荐)
中。 - 客户端访问服务器携带
Token
放入请求头中 (Cookie不建议, 一般放在Authorization
字段中) - 服务器校验
Token
, 成功则返回请求数据,失败则返回错误码。
而 jwt
令牌中的加密内容如下:
- Header: 令牌类型
- Payload: 用户信息
- Signature: 签字, 验证信息, 保证内容不被篡改
只要三者通过验证, 就可以判定令牌有效。
Token 优点
-
Token
可以防范, 或者说是专门防范 CSRF 攻击, 不会被自动加入请求头。 -
Token
存储在报文头的Authorization
字段中。 -
Token
支持跨域, 可以与第三方共享, 具体原理后续会介绍。 -
Token
不依赖于Cookie
在移动端中适配良好。 -
Token
存储在客户端(localStorage), 使服务器无状态化, 减少负担。
Token 缺点
Token
不能管理自己发出的令牌, 如果令牌被盗用, 服务端也难以进行注销。对此Session
的优势就很明显, 可以很好的管控自己的会话。
Credentials 授权
不同适用场景
Token 适用于移动端, 需要第三方共享API, 一次性授权 以及防止CSRF攻击的情况下。
Session 适用于管理会话, 尤其是用户登录, 注销, 改密码这些操作最佳的实践方案依旧是Session。
有没有一种办法可以讲两者的优点结合起来, 弥补缺点?
Credentials
授权便是一种解决方案, 而且广泛应用于现代应用, 比如我们常见的登陆一个网站, 借用QQ账号登陆, 并进行验证第三方应用。
常见应用就是 OAuth
, OAuth
允许用户提供一个授权层, 要求本身是 HTTPS
, 第三方应用是 HTTP
。具体查看 OAuth
一方面在最顶层我们通过 Session 管理用户账号的状态, 另一方面我们可以通过 OAuth 对第三方应用进行授权。
这其实就是典型的 SSO 单点登录 结合 令牌授权。
相关文章推荐
首先非常感谢您的阅读, 您的点赞和关注是对我最好的支持。
如果文章中存在错误, 非常感谢您能够指出, 也非常欢迎您与我进行讨论。
秋天不落叶大佬的 傻傻分不清之 Cookie、Session、Token、JWT
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!