Skip to content

四火的唠叨

一个纯正程序员的啰嗦

Menu
  • 所有文章
  • About Me
  • 关于四火
  • 旅行映像
  • 独立游戏
  • 资源链接
Menu

OAuth2.0 的几种授权流程

Posted on 07/26/202507/26/2025 by 四火

首先,从高维度看,OAuth 是要解决什么问题?

OAuth 要解决的是客户端在不知道和不使用用户密码的情况下,怎么样安全访问并获取用户所拥有的资源的问题。

顺带说一句,经常和 OAuth 一起谈到的 OIDC 则是解决了用户信息(profile)获取的问题。简单说,OAuth 解决了 Authorization 的问题,OIDC 解决了 Authentication 的问题。

OAuth 有几种角色:

  • Resource Owner:资源的拥有者,比方说终端用户;
  • Resource Server:资源服务器,比如用户想要调用的 API;
  • Client:就是用户来进行鉴权和资源操作的客户端,比方说浏览器或者 CLI;
  • Authorization Server:就是专门授权的服务器。

所以 OAuth 就是用户想通过某种机制,通过 Client 和 Authorization Server 交互来获得能够访问资源的 token。

对于 OAuth2.0 的授权流程,可以根据 grant type 来做个归类。下面的图示全部都来自 Auth0 的官方文档。

1. Authorization Code:用户访问 web app,web app 的后端请求 auth server,于是重定向到登录页面,用户输入登录信息,auth server 就给 web app 一个授权码,这个授权码通过 callback URL 返回,而这个参数一般放在这个 url 的参数中,比如:http://…/callback?token=TOKEN。之后 web app 就可以拿着授权码去取 token 了。这种方式不需要用户这边存放任何 secret,但是需要用户参与 consent,并且具备 web app 的后端,因为和 auth server 的交互主要都是 web app 后端完成的。

但是这种方法存在一些 concern,比如说,这个 code 如果在返回途中被截获怎么办,截获者就可以使用这个 code 来获取 token 了。

2. PKCE:对于上述问题,有一个改进的办法,就是使用 PKCE(Proof Key for Code Exchange)来给它增强。基本原理是,客户端生成一个随机字符串 code verifier,根据一个算法 code challenge method 来生成它的 hash(challenge),获取授权码 code 的时候需要把这个 method 和 challenge 带过去;接着,code 正常返回,但之后客户端拿着 code 去获取 token 的时候,需要带上这个 code verifier,这样 auth server 就可以根据之前拿到的 method 和 challenge,以及刚得到的 code 和 code verifier,来校验用户是不是可以得到这个 token。

在这种情况下,如果 code 被劫持,那么对方拿到了 code,却没有 code verifier,也就没什么用。

这种方法是比较推荐的,对于一些 CLI 登录使用这种方法的时候,重定向 URL 可以是一个带有 code 的指向 localhost 的地址以被 CLI 捕获。

3. Device Code:前面说到的 Authorization Code 这种方法还有一个变体,就是对于一些需要用户参与,但是又没有浏览器(或者自动打开浏览器)的场景下,这个重定向到浏览器来获取用户 consent 的过程,被其它方式来取代,这种变体可看做名为 Device Authorization 的流程:

可以看到,上面的浏览器重定向的过程被替换成了返回 code 和 verification url,然后用户使用 verification URL 加上这个 user code 来完成 consent 的过程,在这个过程完成之后,这个 device 才被授权。在这个过程完成之前,需要 app 不断去 poll 检查是不是 device 已经被授权了。

4. Client Credential:前面说到的 Authorization Code 虽然好用,但是需要用户手动登录确认的过程,对于一些没有人参与的 M2M(machine-to-machine)系统而言,这是不现实的。因此在 client id 的基础上,再加上一个 client secret,一样可以完成 auth 的流程。这种场景其实就相当于是 client 和 resource owner 是同一个了:

5. Implicit:这种其实就是上面 Authorization Code 的简化版,去掉了 code 的环节,直接发 code。这种方式在 app 只有前端的场景下(比如 SPA)使用,因为它没法进行后端和 Auth Server 的通信。但是这种方式因为安全性低,因而不推荐,因为即便是 SPA,还是可以用前面说的那种 PKCE 增强的 Authorization Code 方式来实现。

再来看这个 callback 的 URL,和前面提到的 Authorization Code 流程不一样的是,它返回的 token 放在 URL 的 fragment 里面,而不是 query 里面,比如:http://…/callback#token=TOKEN,这样做的好处是这个 TOKEN 不会在浏览器跳转的时候送到服务器,就不容易泄露。

6. Password:这种方式其实就是让 client 获知用户的用户名和密码,属于风险比较大的做法,要求这个 app 是用户百分百信任的——这也就是说,它没有解决 OAuth 本身应该解决的问题,因此很少使用。

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》

×Scan to share with WeChat

你可能也喜欢看:

  1. Issue record: “No thread for socket” about Memcached
  2. Study Notes Of Mason
  3. A page widgetization practice
  4. 常见分布式应用系统设计图解(十一):数据监控系统
  5. 本地部署 Minikube + Docker 记录

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

订阅·联系

四火,啰嗦的程序员一枚,现居西雅图

Amazon C++ Google Groovy Hadoop Haskell Java JavaScript LeetCode Oracle Python Spark 互联网 华为 历史 同步 团队 图解笔记 基础设施 工作 工作流 工具 工程师 应用系统 异步 微博 思考 技术 招聘 数据库 时间 曼联 测试 生活 程序员 管理 系统设计 缓存 编码 编程范型 英语 设计 问题 面试 项目

分类

  • Algorithm and Data Structure (30)
  • Concurrency and Asynchronization (6)
  • System Architecture and Design (43)
  • Distributed System (18)
  • Tools Frameworks and Libs (13)
  • Storage and Data Access (8)
  • Front-end Development (33)
  • Programming Languages and Paradigms (55)
  • Testing and Quality Assurance (4)
  • Network and Communication (6)
  • Authentication and Authorization (7)
  • Automation and Operation Excellence (13)
  • Machine Learning and Artificial Intelligence (6)
  • Product Design (7)
  • Hiring and Interviews (14)
  • Project and Team Management (14)
  • Engineering Culture (17)
  • Critical Thinking (25)
  • Career Growth (57)
  • Life Experience and Thoughts (45)

推荐文章

  • 聊一聊分布式系统中的时间
  • 谈谈分布式锁
  • 常见分布式系统设计图解(汇总)
  • 系统设计中的快速估算技巧
  • 从链表存在环的问题说起
  • 技术面试中,什么样的问题才是好问题?
  • 从物理时钟到逻辑时钟
  • 近期面试观摩的一些思考
  • RSA 背后的算法
  • 谈谈 Ops(汇总 + 最终篇):工具和实践
  • 不要让业务牵着鼻子走
  • 倔强的程序员
  • 谈谈微信的信息流
  • 评审的艺术——谈谈现实中的代码评审
  • Blog 安全问题小记
  • 求第 K 个数的问题
  • 一些前端框架的比较(下)——Ember.js 和 React
  • 一些前端框架的比较(上)——GWT、AngularJS 和 Backbone.js
  • 工作流系统的设计
  • Spark 的性能调优
  • “残酷” 的事实
  • 七年工作,几个故事
  • 从 Java 和 JavaScript 来学习 Haskell 和 Groovy(汇总)
  • 一道随机数题目的求解
  • 层次
  • Dynamo 的实现技术和去中心化
  • 也谈谈全栈工程师
  • 多重继承的演变
  • 编程范型:工具的选择
  • GWT 初体验
  • java.util.concurrent 并发包诸类概览
  • 从 DCL 的对象安全发布谈起
  • 不同团队的困惑
  • 不适合 Hadoop 解决的问题
  • 留心那些潜在的系统设计问题
  • 再谈大楼扔鸡蛋的问题
  • 几种华丽无比的开发方式
  • 我眼中的工程师文化
  • 观点的碰撞
  • 谈谈盗版软件问题
  • 对几个软件开发传统观点的质疑和反驳
  • MVC 框架的映射和解耦
  • 编程的未来
  • DAO 的演进
  • 致那些自嘲码农的苦逼程序员
  • Java 多线程发展简史
  • 珍爱生命,远离微博
  • 网站性能优化的三重境界
  • OSCache 框架源码解析
  • “ 你不适合做程序员”
  • 画圆画方的故事

近期评论

  • rocky on 关于时间管理的一点新的感悟
  • panshenlian.com on 初涉 ML Workflow 系统:Kubeflow Pipelines、Flyte 和 Metaflow
  • panzhixiang on 关于近期求职的近况和思考
  • Anonymous on 闲聊投资:亲自体验和护城河
  • 四火 on 关于近期求职的近况和思考
  • YC on 关于近期求职的近况和思考
  • mafulong on 常见分布式基础设施系统设计图解(四):分布式工作流系统
  • 四火 on 常见分布式基础设施系统设计图解(八):分布式键值存储系统
  • Anonymous on 我裸辞了
  • https://umlcn.com on 资源链接
© 2025 四火的唠叨 | Powered by Minimalist Blog WordPress Theme