使用自己的域名接收 OAuth 回调
使用自己的 Google OAuth 应用时,可以把授权回调地址放在自己的域名下。例如,Google 先回调 https://auth.example.com/oauth/callback,你的服务再返回 302,将浏览器跳转到 Connector 完成授权。
你需要在自己的域名上部署一个 HTTPS 回调端点。域名和证书由你管理,Connector 继续负责换取 token、保存凭据和刷新 token。
本方案适用于 Connector for SaaS 中使用自定义 Client、通过 GET 查询参数返回授权结果的 OAuth provider。先按 Connector for SaaS 使用指南创建 Project。使用系统 Client 时,继续使用 Console 提供的默认回调地址。
准备三个地址
以下地址都以生产环境为例:
| 地址 | 示例 | 填在哪里 |
|---|---|---|
| 你的 OAuth 回调地址 | https://auth.example.com/oauth/callback | Google OAuth client 的 Authorized redirect URIs,以及 OOMOL 服务配置的「自定义回调地址」。两处完全一致。 |
| Connector 回调地址 | https://connector.oomol.com/v1/oauth/callback | 你的回调端点返回的 302 Location。 |
| 产品返回地址 | https://app.example.com/connections/done | 创建授权链接时的 returnUri,用于显示连接结果。 |
授权顺序是:Google → 你的回调端点 → Connector 回调 → 产品返回地址。浏览器会经过 Connector 域名。
第 1 步:部署 302 回调端点
在 auth.example.com 部署 /oauth/callback,收到请求后立即返回 302。下面的代码可以保存为 oauth-callback.ts,使用 bun run oauth-callback.ts 启动,再由你现有的网关提供 HTTPS:
Bun.serve({
routes: {
"/oauth/callback": {
GET(request) {
const query = new URL(request.url).search;
return new Response(null, {
status: 302,
headers: {
Location: `https://connector.oomol.com/v1/oauth/callback${query}`,
"Cache-Control": "no-store",
"Referrer-Policy": "no-referrer",
},
});
},
},
},
});
把回调端点接入已有服务时,保留相同的返回逻辑。Location 的目标固定为 Connector 回调地址,直接拼接收到的原始查询字符串。
- 保留全部参数及其原始编码,包括
code、state、错误参数,以及 QuickBooks 的realmId、Shopify 的hmac等 provider 参数。不要先用URLSearchParams解码再重建。 - 此端点直接返回 302,不需要登录、换取 token 或消费
state。不要从服务端fetchConnector 回调;需要由浏览器跟随跳转。 - 关闭这条路由在应用、网关、CDN、错误上报和 tracing 中的查询参数采集,避免记录授权码和
state。端点直接返回响应,不渲染页面或加载第三方资源。
第 2 步:在 Google 登记回调地址
在 Google Cloud Console 中,创建或打开你的 Web application OAuth client,把以下地址加入 Authorized redirect URIs:
https://auth.example.com/oauth/callback
这里填写你部署的 HTTPS 地址。协议、主机、路径、尾部斜杠和已有查询参数都要与 OOMOL 中的配置一致。Google 对 redirect URI 的要求见 Web Server OAuth 文档。
提交品牌验证时,在 Google Search Console 验证根域名 example.com 的所有权,并将其加入 OAuth 应用的 Authorized domains。用于域名验证的 Google 账号需要关联到对应的 Google Cloud 项目。首页、隐私政策、其他回调地址或 JavaScript origins 使用的域名也在验证范围内,详见 Google 品牌验证要求。
自定义回调地址解决的是回调域名归属问题。应用仍需满足 Google 的其他品牌验证要求;使用敏感或受限 scopes 时,也需按要求完成相应审核。
第 3 步:在 OOMOL 配置自定义 Client
在 OOMOL Console 中:
- 打开「项目」,进入目标项目的「服务配置」。
- 点击「创建服务配置」,选择
Gmail和OAuth2。 - 将「Client 配置来源」设为「自定义 Client」,填写 Google 的 Client ID 和 Client Secret。
- 在「自定义回调地址(可选)」中填写
https://auth.example.com/oauth/callback。 - 创建后复制服务配置 ID,作为后端的
providerConfigId。
「默认回调地址」是转发代码中的目标地址。自定义回调地址留空时,Google 会直接回调这个默认地址。
也可以由后端使用 Project API key 调用 POST https://connector.oomol.com/v1/saas/projects/:projectId/provider-configs,请求头为 Authorization: Bearer <project-api-key>,请求体如下:
{
"service": "gmail",
"slug": "gmail-custom",
"displayName": "Gmail",
"authType": "oauth2",
"oauth": {
"clientConfigSource": "custom",
"clientId": "<google-client-id>",
"clientSecret": "<google-client-secret>",
"redirectUri": "https://auth.example.com/oauth/callback",
"scopes": ["https://www.googleapis.com/auth/gmail.readonly"]
}
}
Project API key 和 Client Secret 只在可信后端或 Console 中使用。示例 scope 用于只读 Gmail;按实际操作配置所需权限。
oauth.redirectUri 必须使用 HTTPS,不能包含用户名、密码或 # 片段。地址中可以预设 tenant 等普通查询参数,但不能预设 state、code、error、error_description、error_uri 或 scope,包括这些参数名的百分号编码形式,以免与授权结果冲突。这些限制针对登记的地址;转发授权结果时仍需完整保留 provider 返回的参数。
只有使用自定义 Client(clientConfigSource: "custom")时才能设置 redirectUri。配置查询返回的 callbackUrl 是实际交给 provider 的回调地址。已有配置需要更换回调地址时,创建新服务配置并用新 ID 发起授权。
第 4 步:发起授权并验证连接
你的后端继续使用原来的授权链接接口,传入新建的服务配置 ID:
POST https://connector.oomol.com/v1/saas/connected-accounts/link
Authorization: Bearer <project-api-key>
Content-Type: application/json
{
"providerConfigId": "<provider-config-id>",
"userId": "customer-1",
"returnUri": "https://app.example.com/connections/done"
}
后端先保存响应中的 data.id 及其所属用户,再让浏览器打开 data.authorizationUrl。用户授权后,你的端点把完整查询字符串交给 Connector;Connector 使用登记的自定义回调地址换取 token,再跳转到 returnUri。
保存账号绑定前,由后端查询连接请求并确认用户和配置相符。完整步骤见 SaaS 授权与连接结果校验。使用 SDK 时,继续调用 ProjectConnector 的连接方法,并传入对应的 providerConfigId。
上线前,可以先用不含真实授权数据的请求检查转发:
curl -sS -D - -o /dev/null \
'https://auth.example.com/oauth/callback?code=test%2Bvalue&state=test-state'
响应应为 302,Location 应为 https://connector.oomol.com/v1/oauth/callback?code=test%2Bvalue&state=test-state。然后完成一次真实授权,并测试取消授权,确认两种结果都能返回产品页面。
常见问题
| 现象 | 检查项 |
|---|---|
Google 返回 redirect_uri_mismatch | Google 登记地址与 oauth.redirectUri 是否完全一致,当前授权是否使用了正确的服务配置 ID。 |
回调报 state 缺失、无效,或 provider 签名错误 | 网关和应用是否原样保留查询字符串,是否错误地将它解码、重建、丢弃或记录后重复消费。 |
QuickBooks 回调缺少 realmId | 是否只转发了 code 和 state。转发完整查询字符串。 |
| 端点返回页面或调用成功,浏览器却没有继续跳转 | 应直接向浏览器返回 HTTP 302 和 Location,而不是在服务端请求 Connector。 |
| 希望授权完成后回到产品页面 | 创建授权链接时设置 returnUri。自定义回调端点始终先转发到 Connector。 |