正式域名与第三方回调

切换站点入口,核对 OAuth、Stripe、Turnstile 和邮件配置,完成正式域名验收。

完成 workers.dev 首次部署后,可以把网站切换到正式域名。本篇使用 https://app.example.com 作为示例,实际操作时将所有地址替换成自己的。

域名购买、接入 Cloudflare、邮件接收和文件域名设置已有域名配置教程。这里聚焦站点切换与依赖该地址的服务。

一、切换前确认准备完成

  • 目标域名已接入部署 Worker 所属的 Cloudflare 账户,Zone 处于可用状态。
  • 项目已完成首次部署,Worker 与资源绑定存在。
  • .env.production 存在,SAAS_SECRET 与本地项目一致。
  • 已决定唯一的正式入口,例如使用 app.example.com,或者直接使用根域名。
  • Turnstile 已准备好正式站点配置,OAuth 与支付回调已经整理好。

Cloudflare Custom Domain 要求域名属于可用的 Zone,已有 CNAME 的同名主机也会影响创建。发现冲突时先确认旧记录的用途,不要直接删除仍在服务其他应用的 DNS。平台要求见Custom Domains 官方说明。

二、运行域名命令

在应用根目录执行:

npm run domain:set -- https://app.example.com

当前脚本会:

  1. 检查账户、Worker、生产环境与密钥一致性。
  2. 运行 doctor:remote。
  3. 在 wrangler.jsonc 中写入目标 Custom Domain。
  4. 更新 .env.production 的 VITE_SITE_URL。
  5. 重新构建、部署,并同步该文件中的非空变量与 Secret。
  6. 检查新域名首页,打印 OAuth 与 Stripe 回调地址。

需要注意,脚本会保留非 Custom Domain 的路由,但用本次目标替换配置中的 Custom Domain 项。它适用于设置当前正式入口,不是一个反复运行就不断追加多个域名的命令。

脚本也不会自动修改第三方平台、R2 文件域名、邮件服务设置或业务中写死的 URL。自定义 hosts、统计允许域名和业务回调仍需按自己的配置核对。

三、域名切换失败时先看哪一步

如果配置写入或构建阶段失败,脚本会恢复这次修改前的本地 wrangler.jsonc 和 .env.production。如果已经进入远程部署,或部署后的健康检查失败,则不能认为域名和远程版本也已自动恢复。

这时检查:

  • 本地配置中的 Custom Domain 与 VITE_SITE_URL。
  • Cloudflare Worker 当前的域名与已部署版本。
  • DNS、HTTPS 和首页响应是否正常。
  • 是否被旧站点地址或代理配置重定向到了其他 Origin。

修复后再重新执行合适的部署操作。domain:set 只检查首页,不运行完整的 verify、数据库迁移和 KV 同步,如果同时修改了业务代码或内容,应先按更新流程发布。

四、核对正式回调地址

以下地址以 .env.production 中的正式 Origin 为准,不带语言前缀:

服务应填写的地址或主机
GitHub OAuth Callback URLhttps://app.example.com/api/auth/oauth2/github
Google Authorized JavaScript originshttps://app.example.com
Google Authorized redirect URIshttps://app.example.com/api/auth/oauth2/google
Stripe Webhookhttps://app.example.com/api/webhooks/stripe
Turnstile 允许主机app.example.com

不要把 /zh-Hans、/en 或登录页路径加到 OAuth Callback 前面,也不要把支付成功跳转页当成 Webhook。

GitHub 与 Google 登录

沿用前面GitHub OAuth和Google OAuth的设置,核对生产 Client ID、Client Secret 与回调属于同一个应用。

本地与生产如何保留回调,要按提供商和应用类型分别处理,不能假设所有 OAuth 应用都支持在同一个字段里填多个地址。特别是为本地开发单独创建过应用时,不要只改回调,却继续使用另一套 Client ID。

启用 Google One Tap 后,除了普通 OAuth 登录,还要单独检查正式站点上的 One Tap。它依赖浏览器环境和来源配置,普通登录成功不能替代这一步。

Stripe Webhook

如果已经按Stripe 支付教程创建了正式 Webhook,核对地址和当前端点的签名密钥即可,不要再创建一个重复端点。

如果尚未创建,可以在 .env.production 中准备正式 STRIPE_SECRET_KEY 和正式 VITE_SITE_URL,然后运行:

npm run webhook:stripe:prod

脚本会检查正式密钥模式,让你确认地址、事件和 API 版本,创建一个新的 Webhook 端点,并把返回的签名密钥写入 .env.production。默认事件清单与版本由 scripts/stripe/webhook.ts 维护,通常保留项目提供的默认选择。

这个命令是创建操作,不是对已有端点的自动更新。创建完成后还需要:

npm run deploy:update

这次更新让 Worker 使用新的 STRIPE_WEBHOOK_SECRET。Webhook 切换期间可能出现尚未同步的事件,应在配置生效后检查失败投递,并确认重试处理结果。

STRIPE_CONNECTION_ID 用于标识支付连接,确定后保持稳定。切换域名通常不需要同时更换它,否则同一支付平台对象可能被当作另一连接的数据处理。

Turnstile

在正式 Widget 的主机列表中加入 app.example.com,并确认 .env.production 中使用这一个 Widget 对应的 Site Key 和 Secret Key。

若已在运行 domain:set 前更新密钥,该命令会一并部署。若绑定域名后才替换密钥,再运行一次 deploy:update。仅更新平台的允许主机而没有修改应用配置时,不必为了这一项重新发布代码。

邮件

邮件发信域名与网站域名可以不同。例如网站使用 app.example.com,邮件通过已验证的 mail.example.com 发出。重点是当前提供商允许所配置的发件人地址,且邮件里的站点链接指向正式 Origin。

domain:set 不会帮你验证 Resend 域名,也不会改变邮件接收规则。部署完成后实际发送注册验证和找回密码邮件,检查发件人名称、送达情况和正文链接。

五、处理 www、workers.dev 与文件域名

绑定 example.com 不会自动绑定 www.example.com。如果需要让两者都可输入,应明确哪个是正式入口,再为另一个地址配置保留路径和查询参数的跳转。具体操作见域名配置中的 www 说明。

当前模板默认 workers_dev: true,domain:set 不会自动将它关闭。正式域稳定后,如果不再需要这个入口,可以在 wrangler.jsonc 改为 false,再运行 deploy:update。关闭之前先确认没有登录回调、Webhook 或业务调用仍依赖旧地址。

如果保留 workers.dev,不要同时把它作为另一套正式 Origin 使用。当前应用会依据允许主机与 VITE_SITE_URL 处理请求,旧地址的重定向也不能代替提供商后台的回调迁移。

R2 文件域名属于独立设置。需要公开文件地址时,按存储与上传配置 publicBaseUrl 和 Bucket 的公开访问。把 publicBaseUrl 改成 false 只影响应用生成的地址,不会自动关闭 Cloudflare 中已经开放的 R2 域名。

六、完成切换验收

打开一个新的浏览器会话,按下面顺序检查:

  1. 首页、文档和主要业务页面使用正式 HTTPS 地址。
  2. 页面内部链接、Canonical、Open Graph 等没有指向旧域名。
  3. 密码登录和已启用的 OAuth 登录能够回到正式站点。
  4. Turnstile 能按预期完成,网络请求没有域名不匹配错误。
  5. 邮件中的验证和重置链接使用正式域名。
  6. Stripe 端点收到了预期事件,Worker 能验证签名并更新业务状态。
  7. 旧入口的访问结果符合预期,没有循环跳转。

域名变化后,不要假设浏览器会把旧域名上的登录 Cookie 自动带到新域名,应重新登录验证。

完成后进入上线验收与日常维护。