OAuth 的工作原理——授权码流程

OAuth 的工作原理,在一张交互式画布上讲清楚:用户、客户端应用、授权服务器与资源服务器之间的授权码流程。

OAuth 让一个应用代表用户去访问另一个服务的数据,全程不接触用户的密码——它用用户的同意换来一个短期令牌。

OAuth 的工作原理——授权码流程

The interactive FlowJam canvas for this explanation — every lane, row and arrow above is a real QueryChart diagram you can open and edit.

How to read this visual

  • 从左到右读三列:授权、令牌交换、受保护资源。
  • 每一行是其中一方在这个故事里的戏份——用户这一行在最上面,资源服务器在最下面,于是用户的同意和服务器的校验一头一尾夹住中间。
  • 跨行跳跃的箭头,比如授权码回到客户端那一条,是各方之间真实的网络消息;行内的箭头则是这一方自己的步骤。

授权环节

流程起点在用户这一行:用户点击“使用服务商登录”,随即交接给“客户端把用户重定向到授权服务器”。这次重定向是 OAuth 的标志性动作:它把用户带出客户端应用、送到服务商那边,“用户登录并批准所请求的权限范围”就发生在那里。真正关键的不是登录,而是授权同意页面——用户在这里精确选择客户端可以做什么。“授权服务器向客户端返回授权码”把控制权交还给应用,但交回来的只是一个授权码,不是令牌。

令牌交换

“客户端用授权码和客户端密钥换取访问令牌”从客户端这一行跨进授权服务器那一行。就在这一步,客户端同时出示它收到的授权码以及已注册的客户端密钥,证明自己是一个合法应用——所以光偷到授权码还不够。“授权服务器签发访问令牌”是同意决定变成一项能力的时刻:一个字符串,写明客户端可以做什么、能做多久。

把令牌花出去

“客户端携带访问令牌调用资源服务器”跨进“资源服务器”这个泳道分组,“资源服务器校验令牌并返回用户数据”是最终的回报。资源服务器从头到尾没见过用户的密码,也没见过授权同意页面——它只检查令牌。“用户在应用里看到自己的数据”在用户这一行合上整个回路:在用户看来,自己只登录了一次,应用就拿到了数据。

Key relationships and takeaways

  • 用户的密码只交给授权服务器——客户端和资源服务器从不经手。
  • 同意(也就是权限范围)才是真正的授予;访问令牌是这份授予的机器可读形式。
  • 授权码有效期很短,没有客户端密钥就毫无用处——两个因素共同保护这次交换。
  • 访问令牌会过期;刷新令牌在后台悄悄换出新的令牌,不必再弹一次授权同意页面。
  • 资源服务器唯一的职责就是校验令牌,这让各方保持解耦。

When to use this visual

  • 向产品团队解释“使用 Google 登录”为什么是安全的,以及授权同意页面到底在问什么。
  • 选择 OAuth 流程:这里的授权码流程,与隐式流程、客户端凭据流程各自适用的场景。
  • 审计在你的集成里,用户凭据和令牌究竟流经了哪些地方。

运作方式

  1. 把各方改名成你的系统

    把四个泳道分组换成你真实的参与方——你的 Web 应用、你的身份提供方(IdP)、你的 API——让边界对应你正在记录的那套系统。

  2. 写上你申请的权限范围

    在用户同意那一步标注实际请求的权限范围,并注明每一项为什么必要,让评审者看得见最小权限的取舍。

  3. 画出刷新路径

    在令牌过期之后加一条分支:客户端出示刷新令牌,换回一个新的访问令牌,全程不出现授权同意页面,最后落在它自己的明确状态上。

  4. 把失败情况建模进去

    补上拒绝分支——用户拒绝同意、授权码无效、令牌过期或被吊销——每一条都标出它产生的错误响应。

常见问题

OAuth 是什么,它为什么存在?

OAuth 是一套委托标准。它让一个应用代表用户去访问另一个服务上的数据,而这个应用自始至终看不到用户的密码。用户在授权服务器上认证一次,并批准具体的权限范围;应用拿到一个可以花出去的令牌。图中的四个泳道分组表示的正是这种关注点分离。

授权码和访问令牌有什么区别?

授权码是用户同意之后客户端拿到的一个短期中间值,它本身什么都不授予。客户端要用这个授权码——连同已注册的客户端密钥——去换访问令牌,后者才是调用资源服务器时真正使用的能力。正是这两步式的交换,让客户端得以在令牌端点证明自己的身份。

为什么用户不把密码直接给应用?

因为应用只需要有限的、可吊销的访问权——读取一份资料,而不是拥有一个账号。如果应用拿到了密码,它就永远拥有全部权限,用户也没法只吊销某一个应用而不去到处改密码。OAuth 用密码换来一个有权限范围、会过期、可以单独吊销的令牌。

权限范围(scope)是什么?

权限范围是用户授予的具体权限,比如“读取邮件”或“写入日历”。它们出现在授权同意页面上,并被编码进访问令牌。资源服务器负责强制执行这些范围,因此一个只有读权限的令牌无法写入——最小权限是写进协议里的,而不是指望客户端自觉。

在 QueryChart(FlowJam)中编辑这张图解

把上面这张 OAuth 流程画布原样打开成你自己的图表,把各方改名成你自己的服务,并标注你实际申请的权限范围。

在 QueryChart(FlowJam)中编辑这张图解

可视化图解中的更多内容