开发者工具 · HTTP / 网络速查

OAuth 2.0 流程

四种 grant 流程图 + 解释

本地处理 · 不上传 免费 · 无需登录 无次数限制 累计 53 次使用

步骤 0 / 0
实线=请求 当前步朱砂 · 已走赤金 虚线=响应
0

点击「下一步」开始演示

关键参数 key parameters

第一节

关于本工具

About

对接第三方登录时,授权码模式、隐式模式、密码模式、客户端模式这四种流程,但凡一步回调地址配错或 scope 没对齐,调试日志能刷一整天。这个工具把每种 grant 拆成节点流程图,点击节点就能看到这一步实际在交换什么参数、返回什么 token。流程图和解释都在浏览器本地渲染,不向任何服务器发送请求——适合在本地开发环境边写代码边对照纠错。

使用场景

第三方登录接入选型

创业公司后端工程师要为 App 接入微信和 Google 登录,面对 authorization code 和 implicit 两种 grant 类型不知如何选。本工具用流程图直观对比两种流程:authorization code 有后端换 token 环节,安全性高但需服务器;implicit 直接返回 access token,适合纯前端单页应用。工程师对照流程图,结合自家后端资源,5 分钟确定选 authorization code 流程,避免上线后 token 泄露风险。

API 权限设计评审

技术经理审查新上线的订单查询 API,发现客户端直接拿用户密码调用接口(resource owner password credentials grant)。本工具展示该 grant 的适用条件:仅限高信任的第一方应用。经理对照流程图发现当前场景是第三方开发者接入,立即要求改为 authorization code + refresh token 方案,防止密码被第三方截获。一次评审避免潜在数据泄露事故。

微服务间令牌传递

架构师设计内部微服务认证方案,需要服务 A 调用服务 B 时不暴露用户密码。本工具展示 client credentials grant 流程:服务 A 用自己的 client_id 和 client_secret 向授权服务器申请 token,无需用户参与。架构师对照流程图确认该模式适用于机器对机器通信,在网关层实现 token 缓存,每 30 分钟刷新一次,避免每次请求都去授权服务器申请,降低延迟 40%。

移动端刷新令牌策略

Android 开发者在实现用户长期登录时,发现 access token 1 小时后过期,用户每天要重新登录 3-4 次。本工具展示 refresh token grant 流程:授权服务器同时返回 access token 和 refresh token,客户端用 refresh token 静默续期。开发者按流程图实现自动刷新逻辑,用户退出 App 后 7 天内无需重新输入密码,日活用户登录失败率从 12% 降至 0.5%。

第三方 SDK 安全审计

安全工程师审计某社交登录 SDK,发现其使用 implicit grant 且未校验 redirect_uri。本工具用流程图展示 implicit grant 的完整请求链:授权请求 → 用户授权 → 重定向返回 token。工程师对照发现 SDK 未实现 state 参数防 CSRF 攻击,且 redirect_uri 可被篡改。借助流程图定位漏洞点,要求 SDK 厂商升级为 authorization code + PKCE 方案,修复高危漏洞。

第二节

使用指南

Getting Started

使用步骤

  1. 1在「授权码模式」标签页点击「获取授权码」按钮,弹出模拟授权页面,显示临时授权码
  2. 2将授权码粘贴到「交换令牌」输入框,点击「交换」按钮,下方区域返回 access_token 与 refresh_token
  3. 3切换到「客户端凭证模式」标签页,直接点击「获取令牌」按钮,无需用户交互即返回 access_token
  4. 4在「隐式模式」标签页点击「获取令牌」按钮,浏览器地址栏出现 #access_token 片段,页面同步显示令牌内容
  5. 5在「密码模式」标签页输入任意用户名与密码,点击「登录并获取令牌」按钮,下方区域返回 access_token 与 scope 信息

输入输出示例

输入输出说明
authorization_code grant 流程:client_id=app123, redirect_uri=https://example.com/callback, scope=openid profile流程图:用户浏览器 → 授权服务器(/authorize?response_type=code&client_id=app123&redirect_uri=...&scope=openid+profile)→ 用户登录并授权 → 授权服务器返回 code 至 redirect_uri → 客户端用 code 向 /token 换取 access_token(附带 client_secret)→ 返回 access_token + refresh_token(可选)。常规:授权码模式是最常用、最安全的 grant,适合有后端的 Web 应用。此示例覆盖了标准参数和完整交互步骤。
client_credentials grant 流程:client_id=service-bot, client_secret=secret456, scope=read write流程图:客户端直接向 /token 发送 POST 请求(grant_type=client_credentials, client_id=service-bot, client_secret=secret456, scope=read+write)→ 授权服务器验证客户端身份 → 返回 access_token(无 refresh_token)。常规:客户端凭证模式用于机器对机器(M2M)通信,无需用户参与。注意 scope 通常由服务器预定义,客户端请求的 scope 可能被截断或忽略。
implicit grant 流程:client_id=spa-app, redirect_uri=https://myapp.com/callback, response_type=token, scope=email流程图:用户浏览器 → 授权服务器(/authorize?response_type=token&client_id=spa-app&redirect_uri=...&scope=email)→ 用户登录并授权 → 授权服务器直接返回 access_token 在 URL 片段(#access_token=...&token_type=Bearer&expires_in=3600)→ 客户端从 URL 片段中提取 token。边界:implicit grant 已不推荐使用(安全风险),但仍在一些旧版 SPA 中出现。注意 access_token 暴露在浏览器 URL 中,且无 refresh_token。
resource owner password credentials grant 流程:username=user@example.com, password=myPass123!, client_id=legacy-app, scope=offline_access流程图:客户端向 /token 发送 POST 请求(grant_type=password, username=user@example.com, password=myPass123!, client_id=legacy-app, scope=offline_access)→ 授权服务器验证用户名密码和客户端身份 → 返回 access_token + refresh_token(若 scope 包含 offline_access)。边界:密码模式仅适用于高度信任的客户端(如官方第一方应用),且要求用户直接提供密码。offline_access scope 会触发 refresh_token 发放,但需注意 token 存储安全。
authorization_code grant 但 redirect_uri 与注册不匹配:client_id=app123, redirect_uri=https://evil.com/callback流程图:用户浏览器 → 授权服务器(/authorize?response_type=code&client_id=app123&redirect_uri=https://evil.com/callback)→ 授权服务器验证 redirect_uri → 发现与注册的 redirect_uri 不匹配 → 返回错误(invalid_request 或 redirect_uri_mismatch)。易错:redirect_uri 必须与客户端注册时完全一致(包括协议、域名、路径),否则授权服务器会拒绝请求。这是防止授权码窃取的关键安全机制。
authorization_code grant 但 code 已过期或重复使用:client_id=app123, code=expired_or_reused_code_xyz流程图:客户端向 /token 发送 POST 请求(grant_type=authorization_code, code=expired_or_reused_code_xyz, ...)→ 授权服务器验证 code → 发现 code 已过期或已被使用 → 返回错误(invalid_grant)。易错:授权码是一次性且有时效的(通常几分钟)。重复使用或过期的 code 会导致 invalid_grant 错误。客户端应妥善处理此错误并提示用户重新授权。
client_credentials grant 但 scope 包含用户级权限(如 openid):client_id=service-bot, scope=openid profile流程图:客户端向 /token 发送 POST 请求(grant_type=client_credentials, scope=openid+profile)→ 授权服务器检查 scope → openid 和 profile 通常需要用户上下文,客户端凭证模式不支持 → 服务器返回错误(invalid_scope)或静默忽略不支持的 scope。易错:客户端凭证模式只能请求与客户端本身相关的 scope(如 API 访问),不能请求需要用户授权的 scope(如 openid, profile, email)。开发者常误配 scope 导致错误。

常见错误对照

1.授权码模式中混淆了 code 和 token

✗ 错误直接拿 authorization_code 去请求资源,以为 code 就是 access_token
✓ 修复先 POST /token 用 code 换 access_token,再用 access_token 请求 /resource

RFC 6749 规定 authorization code 是临时凭证(有效期通常 10 分钟),必须通过 token endpoint 交换 access_token,不能直接用于资源访问。

2.隐式模式中把 access_token 放在 URL fragment 后没提取

✗ 错误回调 URL 是 https://app.com/cb#access_token=abc&token_type=Bearer,但后端代码去读 query string 的 access_token
✓ 修复前端从 window.location.hash 解析 access_token,或用 JS 库自动处理 fragment 参数

隐式模式的 access_token 通过 URL fragment(# 后)返回,不会出现在 query string 或 POST body 中,服务端无法直接获取。

3.密码模式中硬编码 client_secret 到前端

✗ 错误前端 JS 里写死 client_secret: 'myAppSecret123'
✓ 修复client_secret 仅在后端服务器存储,前端使用 PKCE 或后端代理完成 token 请求

client_secret 是机密凭证,暴露在前端等于公开,攻击者可伪造授权请求。RFC 6749 明确 client_secret 只应在机密客户端使用。

4.客户端凭证模式中遗漏 scope 参数

✗ 错误POST /token 只传 grant_type=client_credentials,不传 scope
✓ 修复POST /token 传 grant_type=client_credentials&scope=read write

客户端凭证模式不涉及用户授权,scope 必须显式声明所需权限范围;缺失 scope 时服务端可能返回默认空权限或拒绝请求。

5.刷新令牌时用了错误的 grant_type

✗ 错误POST /token 传 grant_type=refresh_token&refresh_token=xxx,但 body 里还带了 client_id
✓ 修复POST /token 传 grant_type=refresh_token&refresh_token=xxx&client_id=myApp&client_secret=mySecret

刷新令牌的 grant_type 固定为 refresh_token(不是 authorization_code),且需携带 client 凭证(机密客户端)或 PKCE 参数。

6.redirect_uri 与注册时不一致导致授权失败

✗ 错误注册回调是 https://app.com/callback,实际请求传 redirect_uri=https://app.com/cb
✓ 修复redirect_uri 必须与注册时完全一致(包括协议、域名、路径、端口)

RFC 6749 要求 authorization server 必须校验 redirect_uri 精确匹配,防止开放重定向攻击。常见错误是漏了末尾斜杠或大小写差异。

7.state 参数缺失导致 CSRF 攻击风险

✗ 错误发起授权请求时不传 state 参数,回调时也不校验
✓ 修复生成随机 state 值(如 crypto.randomUUID()),授权请求带上 &state=xxx,回调时比对 state 是否一致

state 是 OAuth 2.0 防 CSRF 的核心机制。攻击者可利用无 state 的流程劫持用户授权,RFC 6819 明确要求所有授权请求必须携带并校验 state。

8.PKCE 中 code_challenge_method 设为 plain 但未做哈希

✗ 错误code_verifier=abc123,code_challenge=abc123(直接赋值)
✓ 修复code_verifier=abc123,code_challenge=SHA256(abc123) 的 base64url 编码

plain 方法虽然合法但不安全,RFC 7636 推荐使用 S256 方法。plain 下 code_verifier 直接暴露在授权请求中,失去防拦截意义。

第三节

工作原理

How It Works

核心公式

access_token = JWT(iss, sub, aud, exp, scope, client_id)

变量说明

  • iss令牌签发者,通常是授权服务器 URL
  • sub资源所有者标识,如用户 ID
  • aud令牌接收方,即受保护资源服务器
  • exp过期时间,Unix 时间戳
  • scope授权范围,如 read write
  • client_id客户端应用标识符

示例

授权码流程中,授权服务器为 client_id=app123 签发 access_token:iss=https://auth.example.com、sub=user456、aud=https://api.example.com、exp=1710000000、scope=read。JWT 载荷经 HS256 签名后生成令牌 eyJhbGciOiJIUzI1NiJ9...,客户端携带该令牌访问资源服务器,服务器验证签名与 aud 后返回用户数据。

OAuth 2.0 四种授权流程所有操作在浏览器内完成,无后端请求用户点击“登录”浏览器跳转到授权页用户授权返回授权码授权码模式(Authorization Code)用户点击“登录”浏览器跳转到授权页用户授权返回令牌隐式模式(Implicit)输入用户名密码浏览器直接请求令牌返回令牌密码模式(Password)
用户输入 浏览器处理 输出结果
第五节

常见问题

Q & A
四种 grant 类型我到底该用哪个?

选哪种取决于客户端类型和信任等级。Authorization Code 是最常用、最安全的,适合有后端的 Web 应用;Implicit 已不推荐,因为 access token 直接暴露在 URL 片段里,容易被浏览器历史或中间人截获,现在都用 PKCE 替代它。Client Credentials 用于服务器到服务器的通信(比如后端定时拉数据),不需要用户参与。Resource Owner Password 只应在客户端绝对可信(如自家第一方 App)且无法用重定向时使用,否则密码容易被盗。流程图里每个 grant 都标注了典型场景,可对照判断。

为什么我的回调地址总报 redirect_uri mismatch?

最常见的原因是注册时填的回调地址和实际请求的地址不完全一致——包括协议(http vs https)、端口号、末尾斜杠。例如注册了 https://example.com/callback,但请求时用了 http://example.com/callback 或 https://example.com/callback/,都会报错。另一个坑是本地开发用了 localhost,但注册时写的是 127.0.0.1。本工具流程图里标明了回调地址的校验逻辑:必须精确匹配,不支持通配符或正则。检查注册时的 URI 和请求参数里的 redirect_uri 是否完全一样,包括大小写。

access token 过期了怎么办,一定要重新让用户登录吗?

不用每次都让用户登录。标准做法是配合 refresh token 使用——授权服务器在发 access token 的同时通常会附带一个 refresh token(有效期更长),客户端在 access token 过期后,用 refresh token 去换取新的 access token,这个过程对用户无感。本工具流程图中 Authorization Code grant 的步骤里包含了 refresh token 的交换环节。注意 refresh token 本身也可能过期,且有些服务端会在一段时间未使用后自动撤销它。如果 refresh token 也失效了,才需要用户重新授权。

PKCE 到底解决了什么问题,是不是每次都要用?

PKCE(Proof Key for Code Exchange)解决了 Authorization Code 流程中授权码被拦截的风险。在传统流程中,第三方应用可能把授权码传给自己的服务器,如果通信链路被中间人截获,攻击者就能用这个码换取 token。PKCE 让客户端在发起请求时生成一个加密的 code_verifier,授权服务器在换 token 时验证它的哈希值,即使授权码被截获也无法换 token。现在 OAuth 2.1 已把 PKCE 列为所有公共客户端(如单页应用、移动 App)的强制要求,即使有 HTTPS 也推荐使用。本工具流程图里标明了 PKCE 的介入位置。

scope 参数里可以自定义值吗,还是只能用授权服务器规定的?

scope 的值由授权服务器定义,客户端不能随意发明。常见标准 scope 如 openid、profile、email、api:read 等,但具体哪些可用完全取决于授权服务器的配置文档。如果传了服务器不认识的 scope,一般有两种结果:要么服务器忽略该 scope,要么直接返回错误(invalid_scope)。本工具流程图中的 scope 部分标注了它只是传递用户请求的参数,实际权限范围以服务器返回的 token 中携带的 scope 为准。建议在请求前先查阅授权服务器的 scope 列表,不要假设某个 scope 一定存在。

为什么我用 Implicit grant 时 token 直接出现在 URL 里,这不安全吧?

确实不安全,所以 OAuth 2.1 已经废弃了 Implicit grant。它的设计初衷是给纯前端应用(无后端)一个简化流程,但 access token 直接出现在 URL 的 hash 片段(#access_token=...),容易被浏览器历史、Referer 头、中间人脚本、甚至浏览器扩展读取。而且无法使用 refresh token,导致 token 过期后必须重新跳转授权。现在推荐用 Authorization Code + PKCE 替代它,同样不需要后端,但 token 通过后台交换获取,不暴露在 URL 中。本工具流程图在 Implicit 部分用红色标注了安全隐患,建议优先看旁边的 PKCE 流程。

流程图里的 state 参数是干什么的,不传会怎样?

state 参数用于防止 CSRF(跨站请求伪造)攻击。客户端在发起授权请求时生成一个随机字符串(比如 UUID)并存在本地 session 里,授权服务器在回调时原样返回这个 state。客户端收到回调后比对 state 是否一致,如果不一致,说明可能是攻击者伪造了回调请求。不传 state 的话,攻击者可以诱导用户点击恶意链接,用自己的授权码替换掉合法用户的,从而窃取用户身份。实际生产环境中几乎所有授权服务器都强制要求 state 参数,有些甚至不传就直接拒绝请求。本工具流程图在 Authorization Code 步骤中标注了 state 的生成和校验位置。

隐私保证所有计算与处理均在你的浏览器本地完成,输入数据不会上传服务器,也不会保存或共享。

选择 打开 +新窗口 esc关闭