认证与授权
GoodVision 通过 OAuth 2.0 和 OpenID Connect 提供身份认证。本文介绍如何选择认证方式、获取 Access Token 并接入用户登录。
同一应用支持应用身份和用户身份,两者使用独立的 OAuth Client、API 调用授权和状态。认证成功后,业务 API 仍会校验 Audience、Scope、企业(Organization)、产品访问权限(ProductAccess)和资源归属。
开发者后台登录
开发者后台使用 GoodVision 统一身份服务完成登录。登录过程如下:
- 使用自己的账号通过统一身份服务完成 Authorization Code + PKCE 登录。
- 平台查询当前可访问的企业;首次没有企业时自动准备个人空间,再读取当前访问权限。
- 进入已选择的有效企业,或在可用企业中明确选择。创建应用后,创建者自动成为应用所有者,无需先配置业务角色。
- 普通成员按当前应用权限协作。已有企业或应用权限被撤销时,停止原范围操作,不静默切换到另一企业。
如果是 Partner 代 Customer 调用,服务端还可以提交 acting_organization_id。它只表示“以哪个 Partner 身份行动”,必须由平台根据已批准的委托关系验证;前端或请求 Header 不能自行授予跨组织权限。
Token、Refresh Token 和 ID Token 保存在加密的服务端 Session 中。浏览器仅接收非敏感的用户信息、企业信息和权限摘要。
登录过期后的恢复
后台提示登录过期时,在原页点击重新登录。验证成功后重新检查当前账号和权限:同一账号、同一有效范围可以保留普通草稿,临时 Secret 和删除、所有权等敏感确认会清除。后台不会自动重放创建、保存、付款或转交操作;回到原页核对后明确提交。
补登录后若提示暂时无法核验当前登录与工作区,先点击“重新核验工作区”读取当前状态,无需重复打开登录窗口。仅在登录确实失效时重新登录;重新核验不会自动提交原操作。
首次提交被明确要求重新登录或验证时,返回后仅重新读取当前权限和配置版本。核对保留的草稿,再次确认后才发起新的操作。
已提交但结果未知的请求单独保留原内容、版本和操作编号。同一账号、同一有效范围完成登录或验证后,使用“恢复原请求”确认结果;不要改写原内容或另建操作。新的敏感操作仍需重新确认。
换账号、退出、企业或应用权限失效时,旧资料和操作会清除。依赖暂不可用时按提示重新读取;不要把故障当成没有企业,也不要换用他人账号。
敏感操作验证
图示:重新验证后仍需核对原操作并明确提交;此图不表示实际验证码验证已经完成。
普通登录和日常接入不要求先设置第二因素。所有权转移、向平台客服转交等敏感操作可能要求近期身份验证;按页面进入统一登录页并完成所需验证码验证。所有权转移和平台客服转交要求最近 5 分钟内的验证。
首次配置验证器后,还需完成一次新的验证码验证;保存因素本身不表示本次敏感操作验证完成。验证失败时可重试,取消不会提交原操作。返回后保留获准的普通草稿,敏感确认须再次明确完成,业务请求不会自动重放。
选择认证方式
| 场景 | 调用身份 | 认证方式 | 凭证保存方式 |
|---|---|---|---|
| 后台任务、Worker、服务间调用 | 应用身份权限 | Client Credentials | Client Secret 只放在服务端 Secret Manager |
| 用户登录 Web 应用 | 用户身份权限 | Authorization Code + PKCE(S256)的 public Client | Token 放在服务端 Session / BFF;没有 Client Secret |
| 浏览器直接调用业务 API | 不推荐 | 不直接签发浏览器长期凭证 | 使用 BFF,避免 Token 暴露给浏览器脚本 |
Sandbox Application 可以按用途启用应用身份、用户身份或两者。用户身份需提交精确 Callback URL;应用身份需确认服务端 Secret 保存方式。两者使用不同 Client,不共享 Scope、Subscription、Consent 或 Token。
普通用户登录配置只需一个精确 HTTPS 回调,退出地址和网站来源自动补全,高级设置可按需修改。“API 与权限”和 OAuth/OIDC 页使用同一配置流程。保存成功但尚未回读时,点击“重新读取用户身份”,无需重新配置。操作示意见在当前页面完成配置。
配置 OAuth Client
- 在当前有权创建应用的空间创建 Application;创建者自动成为应用所有者,平台按创建配置准备初始身份。
- 按用途启用应用身份、用户身份或两者;用户身份填写精确回调地址。
- 平台自动校验当前应用关系和身份配置,为启用的身份准备独立 OAuth Client。用户身份强制使用 PKCE,应用身份使用 Client Credentials。
- 需要业务 API 时,再在当前身份下选择 API Product 和最小 Scope;平台校验身份、Scope 策略、数据范围和配额,将权限绑定到该身份的 Client 并启用。仅登录不要求业务 API Subscription。
- 应用身份的 Client Secret 按控制台显示的方式安全获取或轮换;用户身份没有 Secret。
开发者后台不会提供平台管理接口或动态注册入口,也不会返回管理令牌。Secret 专用响应强制 no-store;应用身份的 Secret 默认隐藏,离开凭证页或切换 Application / Organization 后立即清除,轮换会使旧 Secret 立即失效。用户身份不生成 Client Secret,可在 OAuth/OIDC 页自助更新精确回调地址。
每次 API 请求都会检查 Token、Audience、Scope、当前身份的 API 调用授权,以及企业、产品和资源权限。任一条件不满足,请求都会被拒绝。
获取 Sandbox Application 后台服务 Token
下面命令使用当前 Development 或 test-us 部署配置提供的 Issuer,但凭证始终属于当前 sandbox Application。不要使用他人 Token、浏览器 Session 或共享管理员 Token。
使用当前应用的精确 GOODVISION_IDENTITY_ISSUER,读取其 /.well-known/openid-configuration 并核对返回的 issuer。将 token_endpoint 保存为 GOODVISION_TOKEN_ENDPOINT,不要拼接固定身份路径。
curl --request POST \
--url "${GOODVISION_TOKEN_ENDPOINT}" \
--header 'content-type: application/x-www-form-urlencoded' \
--data 'grant_type=client_credentials' \
--data 'client_id=YOUR_CLIENT_ID' \
--data 'client_secret=YOUR_CLIENT_SECRET'调用业务 API 时只使用当前 Application、环境和 API Product 对应的 Token:
curl --request GET \
--url "${GOODVISION_API_BASE}/v1/resource" \
--header "authorization: Bearer ${GOODVISION_ACCESS_TOKEN}"请使用当前应用 API 产品提供的 GOODVISION_API_BASE 和资源路径。上面的 /v1/resource 为占位路径,不能直接调用。
Production 必须使用发布配置提供的 GOODVISION_IDENTITY_ISSUER 及生产 API Product 契约重新获取 Token;不能复用 test-us 的 Issuer、Client 或凭证。
用户登录
使用 Authorization Code + PKCE 接入用户登录:
- 生成高熵
code_verifier和 SHA-256code_challenge。 - 发起授权时携带并保存
state;使用 ID Token 时同时验证nonce。 - 用户只在 GoodVision 统一登录页面提交密码、MFA 或 Passkey。
- 有后端的应用在后端交换 Authorization Code,并将 Token 保存在服务端 Session。
- 验证签名、
iss、aud、过期时间和应用授权上下文。 - 退出时销毁本地 Session,并按契约调用 OIDC End Session Endpoint。
redirect_uri 必须与登记值完全一致,不允许通配符。
授权检查
Access Token 用于身份验证,业务资源还需满足以下授权条件:
| 应用身份权限 | 用户身份权限 |
|---|---|
| Token 来自当前 service Client | Token 来自当前 user Client |
| service API 调用授权和 Scope 已生效 | user API 调用授权和 Scope 已生效 |
| 应用身份已获批并在目标组织有权 | 用户已同意 Scope,且平台委托仍有效 |
| Application 对目标资源有权 | 用户在统一权限服务和目标资源中有权 |
Issuer、Audience、企业、ProductAccess、Entitlement 和具体资源状态也需允许当前操作。任一条件不满足,请求都会被拒绝。
浏览器提交的 organization_id 只能作为候选值,服务端必须重新校验,不能让请求头覆盖服务端授权上下文。
安全说明
- 不记录 Token、Authorization Code、Client Secret 或私钥。
- 不把 Sandbox Token 发送到 Production,反之亦然。
- Token 到期前刷新或重新获取,不能自行延长有效期。
- 同一 Application 的用户身份和应用身份使用不同 Client;Sandbox 与 Production 使用不同 Application 和凭证。
- Secret 泄露或丢失后立即申请轮换,不尝试找回原值。
- 登录页显示成功、Token 中出现某个 Claim,都不能替代 API Product、组织和资源权限检查。
登录后的用户与客户空间
完成登录后,读取 open_id、union_id 和客户空间。产品 API 权限另行配置。