周志明的软件架构课
周志明
博士,远光软件研究院院长,《深入理解 Java 虚拟机》《凤凰架构》等书作者
51443 人已学习
免费领取
课程目录
已完结/共 74 讲
架构师的视角 (24讲)
周志明的软件架构课
15
15
1.0x
00:00/00:00
登录|注册

26 | 凭证:系统如何保证与用户之间的承诺是准确完整且不可抵赖的?

你好,我是周志明。
第 24 讲我给你介绍 OAuth 2.0 协议的时候,提到过每一种授权模式的最终目标都是拿到访问令牌,但我并没有讲拿回来的令牌应该长什么样子,反而还挖了一些坑没有填,即为什么说 OAuth 2.0 的一个主要缺陷是令牌难以主动失效。
所以,这节课我们要讨论的主角就是令牌了。我会带你了解令牌的结构、原理与实现,让你明确系统是如何保证它和用户之间的承诺是双方当时意图的体现、是准确完整且不可抵赖的;另外我还会跟你一起看看,如果不使用 OAuth 2.0 的话,通过最传统的状态管理机制的方式,系统要如何完成认证和授权。
好,那接下来,我们就先来看看 HTTP 协议中最传统的状态管理机制,Cookie-Session 是如何运作的吧。

Cookie-Session:HTTP 的状态管理机制

我们应该都知道,HTTP 协议是一种无状态的传输协议,也就是协议对事务处理没有上下文的记忆能力,每一个请求都是完全独立的。但是我想,肯定很多人都没有意识到 HTTP 协议无状态的重要性。
为什么这么说呢?假如你做了一个简单的网页,其中包含了 1 个 HTML、2 个 Script 脚本、3 个 CSS,还有 10 张图片,那么这个网页要想成功地展示在用户屏幕前,就需要完成 16 次与服务器的交互来获取这些资源。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结
该试读文章来自《周志明的软件架构课》,如需阅读全部文章,
请先领取课程
免费领取
登录 后留言

全部留言(14)

  • 最新
  • 精选
  • zhanyd
    Cookie-Session 相当于坐飞机托运了行李,只要带着登机牌就行了,但是一旦托运了行李,行李就和飞机绑定了,你就不能随意换航班了。 JWT 相当于坐飞机拎着行李到处跑,每次过安检还要打开行李箱检查,而且箱子太小也带不了多少东西,优点是可以随意换航班,行李都在自己身边。

    作者回复: 这个比喻优秀

    2
    103
  • lmdcx
    我有 2 个问题想请教老师: 1. 我没理解 "如果 HTTP 协议不是设计成无状态的,这 16 次请求每一个都有依赖关联" 这句话想表达什么? 这里的"状态"是想表达 TCP 那种状态吗(有序性,完整性...)? 当然有可能是我陷入了"知识陷阱", 我理解的是(就算是有)状态和请求顺序不会有关系, 谈不上影响 2. 是否可以把分布式存储(可以理解为 Redis)和 Token 结合来扬长避短? 网上一些案例(我也认为可以)把 Token 缓存到 Redis 中, 请求来的时候先去 Redis 中查一下, 查到即通过, 查不到则进一步解析验证 查到的时候, 还可以看看有没有"吊销"标识(可能需要考虑有限时长的持久化), 有的话直接报非法. 关于在线人数, 就是统计 Redis 中的合法 Token 数量. 至于信息量的问题, 还是用缓存解决(依旧有缓存一致性和 CAP 的问题). 当然有状态就有 CAP 问题, 但我觉得这个是可以接受的, 至少这个方案应该不劣于单纯的分布式 Session 方案或 Token 方案. 关于 HMAC 这个地方我觉得很容易踩个坑(当然都是没怎么思考的), 比如有人会把 Secret 写死在代码中, 这样太危险了, 特别是这个 Secret 还是有规律的. (如果 Secret 被各种办法"猜出来"或者泄露)很容易被人伪造出来合法 Token, 和拖库的危险差不多.

    作者回复: 问题1:HTTP的无状态,就是“每个请求都可以独立处理”(each request message can be understood in isolation),意味着不应该依赖其他请求的前置动作,不受请求之间顺序关系的影响,文中所举例的假设就是如果请求间有顺序关系依赖会出现怎样的问题(这在现实情况中肯定是不存在的)。你提到的TCP,就属于有状态的协议。 问题2:介绍session-cookies时其实提到了这种方案,不做session同步,而是将session存放在一个公共的数据节点中。将这里的sessiong换成token,就是你所说的方案。这当然是一种可以选择的策略,事实上,对token做黑名单功能,主流的做法就是这种扔到redis里的解决方案,这无疑削弱了token的无状态性,但只要有合理的理由,就是可以考虑的。

    9
  • walnut
    让均衡器采用亲和式的负载均衡算法。 请问这种方法是不是也存在分区容错性问题?

    作者回复: 只要分布式系统,只要有网络,就有出现分区的可能。但亲和式的BL属于【没有共享数据】的分布式系统,不受CAP原理约束。

    3
  • 周翔在山麓(Xiang Zhou)
    牺牲集群可用性和分区容错性那里讲反了吧
    4
  • alexgreenbar
    CAP无处不在,没想到Session也受这个定理约束,按目前微服务系统中常见的实现,把Session放到共享的Redis集群中,按本文的前面部分的讨论,其实是选了CA?
    3
    2
  • 有铭
    我是反复在session-cookie和jwt之间横跳后发觉,想要服务器完全不维持状态数据是不可能的,最后还是回归到维护状态数据这条路上了
    2
  • 老师,请教一下。我们系统是在公网。通过自己的鉴权中心实现的单点登陆。现在公司要求实现那种第三方登陆,如果不用ids4,就在现有自己实现的鉴权中心基础上实现通过微信登陆,这凭证token我该怎么实现啊,微信的token,我鉴权中心怎么去处理,没好的思路
    1
    1
  • Geek_1b2948
    我理解下来,客户端使用密码hash是为了保护明文密码,传输层使用https是为了防止hash被嗅探或篡改,主要目的不一样
    归属地:上海
  • 守望_Wilbur
    Oauth认证产生的令牌,包括access token 和refreshtoken在修改密码之后会立即失效嘛?还是access token继续有效直到用refresh token刷新的时候被判断为失效?不考虑修改密码的场景,由于令牌难以主动失效的情况下,令牌一般是怎么失效的呢?可以麻烦回答一下嘛?
    归属地:广东
  • Geek_d68bf9
    OIDC?
收起评论
显示
设置
留言
14
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部