每个 API 团队都会遇到同一个难题。端点单独运行时一切正常,但一旦有人启用 OAuth 2.0,半数测试套件就开始返回 401。突然之间,你要同时处理授权服务器、短期有效的访问令牌和作用域,而到第三次运行时,手动从 curl 响应中复制令牌到请求头字段就让人厌烦了。
解决办法不是在测试中跳过身份验证,而是将令牌处理纳入测试设置,这样就不再需要手动操作。本指南介绍你几乎会在每份测试计划中遇到的两种流程:适用于代表用户操作的 OAuth 授权码流程(带 PKCE),以及适用于机器对机器调用的客户端凭据流程。如果你想先了解完整的授权类型图谱,我们的 OAuth 2.0 流程概览 会逐一介绍这些流程。
接下来进入实操:在 Apifox中配置 OAuth 2.0 身份验证、获取一次令牌并在多个请求之间复用、让过期令牌自动刷新、在文件夹级别继承身份验证,并测试安全审查会要求检查的失败路径。
对 API 测试最重要的两种流程
OAuth 2.0 定义了多种授权类型,但在日常 API 测试中,你大部分时间都会使用其中两种。根据一个问题进行选择:API 是代表用户操作,还是代表服务操作?
授权码流程(带 PKCE)
授权码流程是获取与用户关联的令牌的标准方式。客户端将用户引导至授权服务器,用户登录并表示同意,服务器携带一次性授权码重定向回来,然后客户端在令牌端点将该授权码换取访问令牌。 RFC 6749 定义了完整流程,详见第 4.1 节。
PKCE(代码交换证明,RFC 7636) 可强化这一交换过程。客户端生成一个随机验证器,随授权请求发送经过哈希处理的质询,然后在兑换授权码时证明自己持有原始验证器。截获授权码的攻击者无法使用它。oauth.net 建议每次授权码交换都使用它,包括机密客户端。
请在端点行为取决于用户身份时使用此流程进行测试: GET /orders 仅返回调用者订单的接口、受角色限制的管理员端点、按用户设置的速率限制。
客户端凭据授权流程
该 OAuth 2.0 客户端凭据 授权会完全跳过用户。客户端使用自身的 ID 和密钥进行身份验证,并接收一个代表应用本身的令牌。在令牌端点执行一次 POST 请求,无需浏览器,也无需重定向:
curl -X POST https://auth.example.com/oauth/token \
-d grant_type=client_credentials \
-d client_id=orders_service \
-d client_secret=s3cr3t_value \
-d scope="orders:read orders:write"
这是机器对机器 API 使用的流程:内部微服务、cron 作业、调用部署 API 的 CI 流水线。它也是自动化测试的主力流程,因为整个过程不需要人工参与。如果你的测试环境允许你创建测试客户端,那么除非被测内容正是用户身份,否则所有场景都使用客户端凭据授权。
在 Apifox 中配置 OAuth 2.0 身份验证
Apifox 将 OAuth 2.0 视为一流的身份验证类型。你只需在请求或文件夹的 Auth 选项卡中配置一次,平台就会处理令牌的获取、附加和刷新。支持的授权类型包括授权码、授权码(使用 PKCE)、客户端凭据、密码凭据和隐式授权。
下面介绍上述两种流程的配置方法,使用的是一个虚构的订单管理 API。
客户端凭据设置
打开请求(或者更好地说,打开文件夹;下文会详细说明),将认证类型切换为 OAuth 2.0,并选择 Client Credentials 作为授权类型。填写:
- Access Token URL:
https://auth.example.com/oauth/token - Client ID:
orders_service - Client Secret: 你预先配置的密钥
- Scope:
orders:read orders:write(在高级选项中设置)
Apifox 提供两种传递凭据的方式:通过 Basic Auth 标头,或放在请求正文中。请根据授权服务器的要求选择;Auth0 和 Okta 两者都接受,但一些内部服务器只解析请求正文。
点击 获取令牌. Apifox 调用令牌端点,存储结果,并显示令牌及其有效期。此后,每次发送都会将其附加到 Authorization 请求头,并使用 Bearer 前缀。无需复制粘贴,也无需 {{token}} 变量传递。
使用 PKCE 配置授权码
要测试用户上下文,请将 Authorization Code (With PKCE) 选为授权类型。PKCE 在 Apifox 中是独立的授权选项,而不是复选框。你还需要填写几个字段:
- Auth URL:
https://auth.example.com/oauth/authorize - Access Token URL:
https://auth.example.com/oauth/token - Callback URL: 由你的服务提供商注册的重定向 URI
- Client ID 和 Client Secret: 来自你的 OAuth 应用注册信息
点击 获取令牌 并且 Apifox 会打开一个指向登录页面的浏览器窗口。请以测试用户身份登录,批准同意页面,令牌就会返回并存入之前相同的托管槽位。如果你的提供商在访问令牌之外还返回 OpenID Connect ID 令牌,“所用令牌类型”选项可以让你切换要附加的令牌;当被测 API 验证 ID 令牌时,这一选项很有用。
一个实用建议:为需要覆盖的每种角色各准备一个专用测试用户(买家、管理员、只读审计员)。以每个用户身份获取令牌并重新运行相同场景,是验证基于角色的访问规则的最快方式。
令牌复用与自动刷新
访问令牌会过期,通常在一小时内。在 Apifox 处理这一问题之前,令牌过期意味着运行失败并需要手动重新获取,而这正是团队最终会学会忽略的那类不稳定故障。
现在,当授权服务器签发了刷新令牌时,Apifox 会自行刷新 OAuth 2.0 令牌,这项功能已随 六月更新。当存储的访问令牌过期时,Apifox 会使用刷新令牌获取新的访问令牌,并在发送请求前将其替换进去。你还可以在高级设置中将其指向自定义刷新令牌 URL,如果你的提供商将这两个端点分开。
对于客户端凭据,许多服务器会完全跳过刷新令牌(规范允许这样做,因为客户端可以随时重新进行身份验证)。实际使用中这并不会造成问题:使用 获取令牌 只需点击一下,而计划任务或 CI 运行可以在每次运行开始时请求一个新令牌。
在文件夹层级继承身份验证
在每个请求上配置 OAuth,层级就不对了。Apifox 允许你在文件夹上设置身份验证,文件夹中的请求会继承其父级的配置。在“Orders API”文件夹上设置一次 OAuth 2.0 后,其下的每个请求(包括队友在下个迭代中新增的请求)都会发送同一个托管令牌。
这在多步骤测试场景中最为重要。一个结账场景可能会串联 POST /carts, POST /carts/{id}/items, 以及 POST /orders。在文件夹级认证下,三个步骤共享一个令牌和一套配置。当令牌在场景执行过程中途中过期时,自动刷新会处理这种情况。而当安全团队轮换客户端密钥时,你只需更新一个文件夹,而不是四十个请求。
请求仍可覆盖父级配置,这正是负向测试所需要的。下面详细介绍这些测试。
测试失败路径
正向流程的 OAuth 测试可以证明令牌流程正常运行。失败路径测试则可以证明你的 API 正在强制执行认证。跳过这些测试,就等于信任框架的默认行为。下面是值得自动化的三个用例;如需复习每个状态码应表示的含义,请参阅我们对 API 密钥和 Bearer 令牌.
令牌已过期或缺失:预期为 401
在场景中复制一个请求,并将其继承的认证覆盖为不使用认证,或使用一个硬编码、早已失效的 Bearer 令牌,例如 Bearer expired_token_do_not_rotate。断言:
- 状态码等于
401 - 该
WWW-Authenticate响应头存在(RFC 6749 的配套标准 RFC 6750 要求该响应头存在) - 响应正文不得泄露堆栈跟踪或内部主机名
这里返回 200 是一个严重错误。返回 403 是一种值得提工单的设计异味:服务器应区分“我不知道你是谁”和“我知道你是谁,但拒绝访问。”
作用域错误:预期为 403
配置第二个测试客户端,将其权限限制为 orders:read,获取其令牌,并调用类似 POST /orders。断言状态码为 403 并且,如果你的 API 遵循 RFC 6750,WWW-Authenticate 请求头中包含 error="insufficient_scope"。此测试可以捕获这种经典的配置错误:某些路由在网关处检查了作用域,而其他路由却忘记检查。如果作用域对你的团队来说是新概念,OAuth 2.0 作用域详解 介绍如何划分作用域。
无效客户端:预期令牌端点返回清晰的错误信息
将请求直接发送到 https://auth.example.com/oauth/token 使用伪造的 client_secret。根据 RFC 6749 第 5.2 节,服务器应返回 400 (或401 用于客户端身份验证失败)并附带一个 JSON 请求体,其中包含 "error": "invalid_client"。对两者都进行断言。授权服务器也是 API,其错误契约也是你接口暴露面的一部分。
在测试场景中对令牌响应进行断言
令牌端点除了 invalid-client 情况外,还应有单独的测试覆盖。在测试场景中添加一个直接调用令牌端点的步骤,然后为响应附加断言:
access_token存在且非空token_type等于bearer(根据规范不区分大小写)expires_in大于 0 且符合你的策略,例如不超过 3600scope与请求的内容相匹配,从而捕获服务器静默缩减授权范围的情况
Apifox 的测试场景让你可以将这些内容作为响应 JSON 上的可视化断言添加,无需编写脚本,并且你可以提取 access_token 到变量中,以便在后续步骤中使用,当你想测试原始握手而不是使用托管身份验证时。将该场景接入 CI 运行流程,这样行为异常的授权服务器会使构建失败,而不会在生产环境中以神秘的 401 错误形式暴露。
常见问题
我应该使用哪种 OAuth 流程进行 API 测试?
对于任何机器对机器的场景以及大多数自动化测试套件,请使用客户端凭据,因为它不需要浏览器交互。当测试依赖用户身份时,请使用带 PKCE 的授权码流程:按用户进行数据隔离、角色检查或同意行为测试。在新的测试计划中,避免使用隐式授权和密码授权;这两种授权方式在 当前 OAuth 指南。
如何在 Apifox 中自动刷新过期令牌?
在 Auth 标签页中配置 OAuth 2.0,并使用 Get Token 获取令牌。当授权服务器返回刷新令牌时,Apifox 会在访问令牌过期时刷新访问令牌,无需你重新进行身份验证;如果你的提供商使用单独的刷新令牌 URL,还可以在高级设置中设置该 URL。对于不包含刷新令牌的客户端凭据配置,重新运行 Get Token 即可获取新的令牌。
场景中的每个请求都可以共用一个 OAuth 令牌吗?
可以。在父文件夹上设置 OAuth 2.0 配置,里面的请求会继承该配置,因此多步骤场景会使用同一个受管理的令牌运行。单个请求仍然可以覆盖文件夹配置,这样就能将负向测试(令牌过期、错误的作用域)插入同一场景中。
OAuth 保护的 API 中,401 和 403 分别意味着什么?
身份验证失败时返回 401:令牌缺失、已过期或格式错误。令牌有效但权限不足时返回 403,例如缺少 scope。将二者混淆会破坏客户端的重试逻辑,因为 401 会告知客户端重新进行身份验证,而 403 会告知客户端停止。请参阅我们的 JWT 身份验证测试指南, 深入探讨令牌本身的验证。
开发必备:API 全流程管理神器 Apifox
介绍完上文的内容,我想额外介绍一个对开发者同样重要的效率工具 —— Apifox。作为一个集 API 文档、调试、设计、测试、Mock、自动化测试于一体的工具,Apifox 是目前提升研发效率的首选。
如果你正在开发项目,不妨试试其极其友好的界面设计,它完全兼容 Postman 和 Swagger 数据格式,导入数据非常方便,,即使是新手也能很快上手,点击这里即可注册使用。

值得一提的是,除了个人和常规团队使用,针对有高安全合规要求、或需要在内网环境协作的企业,Apifox 还提供了深度定制的私有化部署方案。
获取专属报价与部署方案
详细的私有化部署系统架构与安全白皮书
针对您公司规模的专属报价单
免费的 1v1 专属产品演示 (Demo) 机会