Skip to Content

OAuth 授权

平台支持 authorization_code、refresh_token 和受限的 client_credentials。所有用户授权请求必须使用 PKCE,算法固定为 S256。

端点与调用方

以下地址均在 开发者中心 → 应用接入配置 → 服务地址 获取,使用分配给当前客户端的完整值;占位符说明见 接入概览。

端点调用方用途
{AUTHORIZATION_ENDPOINT}用户浏览器展示登录和授权页面
POST {TOKEN_ENDPOINT}第三方应用换取或刷新令牌
GET {USERINFO_ENDPOINT}第三方应用使用 Access Token 获取用户身份

API 域名上的 GET/POST /oauth/authorize 由平台授权页面使用,需要平台账号登录态;第三方应将浏览器跳转至网站授权页面,无需自行调用平台授权确认接口。

用户授权请求

将下列参数编码为授权页面的 URL query。Scope 使用空格分隔,所有 URL 参数需进行 URL 编码。

参数类型要求说明
response_typestring设为 code当前接入流程为授权码模式
client_idstring必填已审核、已启用的客户端编号
redirect_uristring必填精确匹配已登记的回调地址
scopestring必填至少一个权限,必须属于该客户端已批准范围
statestring必填每次请求独立生成,绑定发起授权的会话;回调时校验
code_challengestring必填BASE64URL(SHA256(code_verifier)),不带 = 填充,长度 43
code_challenge_methodstring必填固定为 S256
noncestring条件必填请求包含 openid 时必填,绑定本次授权会话
promptstring可选省略时允许复用有效授权;consent 强制展示确认页。当前不支持 none 或其他值

code_verifier 在接入方生成并保存,不放入授权 URL。允许长度为 43–128,字符集合为字母、数字和 - . _ ~。每次授权独立生成 verifier、state 和 nonce;回调换码复用该次授权的 verifier。

授权请求结构
{AUTHORIZATION_ENDPOINT}?response_type=code&client_id={CLIENT_ID}&redirect_uri={URL_ENCODED_REDIRECT_URI}&scope=openid%20profile&state={STATE}&nonce={NONCE}&code_challenge={CODE_CHALLENGE}&code_challenge_method=S256

授权确认与短时复用

用户在确认页主动勾选“15 分钟内不再询问”后,同一应用在当前登录会话中可复用该授权。该项默认不勾选;管理员可缩短显示时限或关闭,硬上限为 15 分钟。第三方不传入免确认时长,也不能替用户开启。

复用要求:登录态有效、授权未过期或撤销、本次权限是已同意权限的子集,且应用身份、已批准权限、回调地址和相关商户资料等授权条件没有变化。时间从最后一次明确同意计算,复用不续期。退出登录、切换账号或条件不满足时,重新展示确认页。旧登录会话在重新登录前可能不提供记住选项。

用户在 设置 → 已授权应用 撤销;平台管理员在 系统管理 → 属性管理 → OAuth 授权安全策略 配置上限,0 表示关闭。复用只省略确认页,每次仍签发新的单次授权码;接入方必须为每次请求生成并校验 state、nonce、PKCE。prompt=consent 可要求本次重新确认。当前不支持 prompt=none,也不提供无需平台登录态的后台静默登录。

授权回调

平台将浏览器重定向至请求中的 redirect_uri,并添加以下 query 参数:

结果参数接入方处理
用户同意code、原始 state先校验 state 与发起会话一致,再换取令牌
用户拒绝error=access_denied、原始 state校验 state 后结束本次授权,由用户决定是否重新发起

授权码有效期为 5 分钟,且只能使用一次。换码时授权码会被消费,后续参数校验失败也不能重复使用;invalid_grant 后应重新发起授权。错误或未知 state 不应触发换码。回调结果不等同于订单支付结果。

令牌请求

POST {TOKEN_ENDPOINT} Content-Type: application/x-www-form-urlencoded

接口同时支持 JSON 请求体;以下定义统一以表单为例。客户端凭据放在请求体中,当前接口不通过 HTTP Basic 请求头读取 client_id 和 client_secret。

公共参数

参数类型要求说明
grant_typestring必填authorization_code、refresh_token 或 client_credentials
client_idstring必填客户端编号
client_secretstring条件必填机密客户端所有令牌请求必填;公共客户端不使用

授权码交换

grant_type=authorization_code 时附加:

参数类型要求说明
codestring必填本次回调返回的授权码
code_verifierstring必填与授权请求的 challenge 对应的原始 verifier
redirect_uristring必填与本次授权请求完全一致
curl '{TOKEN_ENDPOINT}' \ --data-urlencode 'grant_type=authorization_code' \ --data-urlencode 'client_id={CLIENT_ID}' \ --data-urlencode 'code={CODE}' \ --data-urlencode 'code_verifier={CODE_VERIFIER}' \ --data-urlencode 'redirect_uri=https://app.example.com/oauth/callback'

机密客户端在同一请求中增加 --data-urlencode 'client_secret={CLIENT_SECRET}'。

刷新令牌

grant_type=refresh_token 时附加:

参数类型要求说明
refresh_tokenstring必填同一客户端最近一次获得的 Refresh Token

Refresh Token 成功使用后被消费,并返回一组新令牌。接入方需串行刷新、原子替换旧值,不能并发复用旧 Refresh Token。刷新会验证用户授权及账号状态,失败返回 invalid_grant 等错误;已消费的令牌无法重放。

服务端授权

grant_type=client_credentials 仅允许已绑定商户的机密客户端。附加参数:

参数类型要求说明
scopestring必填空格分隔,仅允许已批准的 merchant.profile.read、products.read

该流程不需要用户、回调或 PKCE,返回的令牌不能调用用户信息、订单或支付接口。请求示例见 Client Credentials。

令牌成功响应

HTTP 200,直接返回 JSON 对象。

字段类型返回条件说明
access_tokenstring所有成功授权方式用户信息及 OpenAPI 的 Bearer 凭据
token_typestring所有成功授权方式Bearer
expires_ininteger所有成功授权方式Access Token 有效秒数;以响应值为准,不应硬编码
scopestring所有成功授权方式空格分隔的实际权限
refresh_tokenstring授权码交换、刷新后续刷新使用的新凭据
id_tokenstring当前授权码交换、刷新响应均返回不可替代 Access Token;不能将仅解码结果视为已验证身份

Client Credentials 不返回 Refresh Token;Access Token 到期后用客户端凭据重新请求。

用户信息

GET {USERINFO_ENDPOINT},请求头 Authorization: Bearer {ACCESS_TOKEN},要求用户授权令牌及 openid 权限。

HTTP 200 响应:

字段类型返回条件说明
substring必定返回当前客户端范围内的用户标识,用于关联接入方账号
preferred_usernamestring同时授权 profile平台用户名
nicknamestring同时授权 profile平台昵称
emailstring同时授权 email 且账号已设置邮箱用户当前邮箱地址
email_verifiedboolean返回 email 时平台是否已验证该邮箱;未验证为 false
openid profile email 响应示例
{ "sub": "pairwise-user-subject", "preferred_username": "example-user", "nickname": "示例用户", "email": "user@example.com", "email_verified": true }

未授权 email 时不返回这两个字段;未设置邮箱时也省略两者。授权范围包括 email 不代表账号一定有邮箱或邮箱已经验证。邮箱可能变更,不应用作账号唯一标识。邮箱字段从 UserInfo 获取,当前 ID Token 不包含邮箱声明;email 的字段含义遵循 OpenID Connect Scope 定义 。

用户撤销或管理员调整客户端权限后,旧授权码、Access Token、Refresh Token 失效;重新授权也不会恢复旧令牌。

同一用户在不同客户端的 sub 可以不同。用户名和昵称不应作为唯一标识。

当前未提供公开 OIDC Discovery / JWKS 端点。身份接入可通过 Access Token 请求 userinfo;需要独立验证 ID Token 的集成应先确认签名验证方式,不能跳过验签、受众和有效期校验。

错误响应

OAuth 错误为 JSON 对象:

{"error":"invalid_grant","error_description":"..."}

error 为分类名称,error_description 为诊断文本,不作为稳定的程序分支依据。请求参数错误、无效授权码或 Scope 通常为 HTTP 400;客户端认证失败为 401 invalid_client。资源接口还可能返回 401 invalid_token 或 403 insufficient_scope。完整检查项见 错误与排查。

最后更新于