使用生成式 AI 接入机密客户端 开发人员

上次更新:2026年8月12日

使用生成式 AI 接入机密客户端

本文面向希望借助生成式 AI、以机密客户端接入 OAuth 2.1 / OpenID Connect(OIDC)登录的开发者。即使尚未系统学习相关协议,也可以按照本页步骤完成基础接入。

整个过程只需要四步:

  1. 把本页提供的提示词交给 AI。
  2. 将 AI 输出的 Redirect URI(重定向 URI)登记到摇月开发者门户的标识符向导(选机密客户端)。
  3. 将开发者门户生成的 client_idclient_secret 配置为服务端环境变量。
  4. 启动应用并测试**“通过摇月 Swaymoon 通行账户登录”**按钮。

本页提示词面向包含可保管密钥的服务端运行时的应用。若项目以纯 HTML、静态站点或纯浏览器端形态交付,请改读《使用生成式 AI 接入非机密客户端》与《Python 最小可运行示例》,不要编造 client_secret

如果不确定项目架构,提示词会要求 AI 先检查:是否存在传统后端、API Route、Serverless Function 或 BFF(Backend for Frontend)等可安全保存 client_secret 的运行时。

关键安全要求

client_secret 是机密客户端用于身份认证的凭证,只能保存在服务端。不得将其发送给 AI,也不得将其写入前端代码、客户端可见的环境变量或 Git 仓库。非机密客户端不会发放 client_secret

第一步:把提示词交给 AI

在 AI 编程工具中打开项目,然后完整复制以下提示词。

无需向提示词补充任何真实凭证。AI 应先完成代码实现,再输出需要登记的 Redirect URI。

请在当前项目中接入“摇月 Swaymoon 通行账户”登录,并直接完成代码修改和必要测试。

交互目标:
- 在合适的登录页面添加“通过摇月 Swaymoon 通行账户登录”按钮。
- 用户选择按钮后前往摇月官方页面登录。
- 登录成功后返回当前应用,并保持登录状态。

请先检查项目的部署与运行时形态:
- 如果项目有服务端、API Route、Serverless Function 或 BFF,可安全保管 client_secret,请继续按机密客户端实现。
- 如果项目是纯 HTML、纯静态站点或令牌交换只能发生在浏览器中的纯 SPA:不要使用机密客户端;应改用门户的非机密客户端(clientType=public,认证方式 none),并按无 client_secret 的 PKCE 令牌交换实现(参考《使用生成式 AI 接入非机密客户端》《Python 最小可运行示例》)。
- 任何情况下都不得把 client_secret 放到浏览器或前端代码中。

接入配置:
- Issuer:https://api-passport.swaymoon.com
- Discovery:https://api-passport.swaymoon.com/.well-known/openid-configuration
- 流程:Authorization Code + PKCE(S256)
- 有服务端时客户端认证:client_secret_basic(机密客户端);纯前端时使用 none(非机密客户端,表单携带 client_id + code_verifier,无 refresh_token)
- ID Token 签名算法:ES256
- 登录入口优先使用:GET /auth/swaymoon
- 回调入口优先使用:GET /auth/swaymoon/callback
- 默认只申请 openid。仅在当前产品确实需要时增加 email 或具体资料细项(如 name、picture),不要用整包 profile 一把拿走。

实现要求:
1. 优先使用适合当前框架、仍在维护的 OIDC 客户端库,并通过 Discovery 获取协议端点。
2. 在服务端生成并保存 state、nonce 和 PKCE code_verifier,回调时严格校验。
3. 只在服务端使用 SWAYMOON_CLIENT_ID 和 SWAYMOON_CLIENT_SECRET 换取令牌。
4. 使用 JWKS 校验 ID Token 的 ES256 签名,并校验 iss、aud、exp、iat 和 nonce。
5. 在服务端调用 UserInfo,确认其中的 sub 与 ID Token 的 sub 一致。
6. 使用 sub 查找或创建本地用户,不要使用 email 作为用户主键;按令牌 scope 解释资料字段,未授权项会是默认占位值而非真实数据。
7. 创建当前应用自己的安全登录会话。浏览器只保存设置了 HttpOnly 和合理 SameSite 属性的应用会话 Cookie,不保存摇月令牌;生产环境使用 HTTPS 时必须设置 Secure。
8. 登录后的跳转目标只允许站内相对路径或可信白名单,避免开放重定向。
9. 不得在 localStorage、sessionStorage、普通 Cookie、日志、错误页面或测试快照中保存密钥和令牌。
10. 不得使用 NEXT_PUBLIC_、VITE_、NUXT_PUBLIC_、PUBLIC_ 等公开变量名前缀保存密钥。
11. 创建不含真实值的 .env.example,并确保本地密钥文件已被 .gitignore 忽略。
12. 不要询问或要求我把真实 client_secret 发到对话中。

请在完成后提供清晰、可执行的接入说明:
1. “请复制下面这整行到摇月开发者门户”,然后单独输出本地开发使用的完整 Redirect URI。
2. 生产环境应登记的完整 Redirect URI;如果目前不知道正式域名,请明确标出需要替换的部分。
3. 我需要在服务端配置哪些环境变量,以及应在当前框架或部署平台的哪里填写。只显示变量名,不显示或猜测密钥值。
4. 如何启动项目、找到登录按钮并完成一次测试。
5. 你修改了哪些文件。

AI 完成代码修改后,定位其输出的以下内容:

请复制下面这整行到摇月开发者门户:
http://127.0.0.1:3000/auth/swaymoon/callback

以上地址仅为示例。端口和路径以 AI 根据当前项目输出的结果为准。

第二步:登记 Redirect URI

什么是 Redirect URI?

Redirect URI 即开发者门户向导中的「重定向 URI」,是预先登记在 OAuth 客户端中的回调端点。用户在摇月通行账户完成身份认证和授权确认后,授权服务器会将浏览器重定向至该地址,并携带授权响应,例如 codestate

Redirect URI 通常对应 AI 在应用后端创建的回调路由,不是普通主页。该路由负责校验授权响应、换取令牌、创建应用会话,并将用户重定向至登录后的页面。

Redirect URI 通常由应用 Origin 和回调路径组成。Origin 包含 scheme、host 和 port,例如 https://app.example.comhttp://127.0.0.1:3000

应用 Origin + /auth/swaymoon/callback

例如:

使用场景应用地址Redirect URI
本地开发http://127.0.0.1:3000http://127.0.0.1:3000/auth/swaymoon/callback
正式网站https://app.example.comhttps://app.example.com/auth/swaymoon/callback

请优先使用 AI 根据项目路由和运行端口输出的完整 Redirect URI,不要自行推测。

Redirect URI 的精确匹配要求

授权请求中的 redirect_uri 必须与开发者门户中的登记值逐字符一致。这项校验用于防止授权码被发送至未经登记的地址。以下差异均会被视为不同的 URI:

  • http://https:// 不同;
  • 127.0.0.1localhost 不同;
  • 30003001 端口不同;
  • 有无末尾 / 也可能不同。

因此,请完整复制 AI 输出的 URI,不要手动修改。如果 AI 分别输出本地环境和生产环境的 URI,请在开发者门户中逐条登记。

在开发者门户填写

  1. 登录 摇月开发者门户
  2. 进入标识符,点击 + 打开「注册应用标识符」向导。
  3. 描述:填写用户在同意页可识别的名称;有服务端时选择机密客户端
  4. 图标:可用默认图标,或上传并裁剪后继续。
  5. 重定向 URI:粘贴 AI 给出的完整 Redirect URI(本地与生产可分别添加)。
  6. 功能:保持 openid 必选。需要联系邮箱时再设置 email(必选 / 可选 / 不申请);资料细项亦可选或必选(必选须填理由与隐私政策)。用户可能选择隐私邮箱,你方按普通 email 处理即可。详见《权限与同意》。
  7. 确认后点「注册」。

创建成功后,开发者门户会提示客户端凭证(请立即保存):

  • client_id:OAuth 客户端的公开标识,用于标识发起授权请求的应用;
  • client_secret:机密客户端的认证凭证,仅在创建时显示一次,必须立即安全保存(非机密客户端无此字段)。

第三步:配置客户端凭证

AI 通常已经在项目中创建了类似下面的配置模板:

SWAYMOON_ISSUER=https://api-passport.swaymoon.com
SWAYMOON_CLIENT_ID=
SWAYMOON_CLIENT_SECRET=
SWAYMOON_REDIRECT_URI=

请按照 AI 针对你的框架给出的说明,在服务端环境变量中填写真实值。

  • 本地开发时,通常填写到已被 .gitignore 忽略的 .env.local 或同类文件中。
  • 部署网站时,填写到部署平台的 Environment Variables、Secrets 或“环境变量”设置页面中。
  • SWAYMOON_REDIRECT_URI 填写刚才登记的完整 Redirect URI。
  • 如果 AI 还要求配置应用会话密钥,请在本地终端按照它给出的命令生成随机值,再自行填入环境变量,不要把生成结果发回 AI。

客户端凭证的安全要求

以下操作均被禁止:

  • 不要把 client_secret 粘贴到 AI 对话中;
  • 不要把 client_secret 写进 HTML、React、Vue 或其他前端文件;
  • 不要使用 NEXT_PUBLIC_VITE_NUXT_PUBLIC_PUBLIC_ 等前端公开变量保存它;
  • 不要把包含真实密钥的 .env 文件提交到 Git;
  • 不要把 Access Token、ID Token 或 Refresh Token 保存到 localStorage

如果 AI 要求将 client_secret 写入前端,请停止采用该实现,并改为由服务端或 BFF 完成令牌交换。

第四步:测试登录

  1. 按照 AI 给出的命令启动项目。
  2. 打开包含登录按钮的页面。
  3. 选择**“通过摇月 Swaymoon 通行账户登录”**。
  4. 在摇月官方页面完成登录和授权。
  5. 浏览器返回你的应用,并显示已登录状态。

用户侧只需显示一个登录按钮。授权重定向、回调校验、令牌交换和应用会话创建均由服务端完成。

<a href="/auth/swaymoon">通过摇月 Swaymoon 通行账户登录</a>

实际按钮的组件实现和样式由 AI 根据当前项目生成,无需手动复制以上 HTML。

常见问题

可以将错误信息提供给 AI 辅助排查,但应先移除其中的客户端凭证、令牌和完整回调查询参数。不要发送包含 code=state= 的完整浏览器地址。

问题排查方式
提示 Redirect URI 不匹配重新复制 AI 输出的完整 URI,并与开发者门户中的登记值逐字符比较
提示 invalid_client检查 client_idclient_secret 是否填在服务端环境变量中,修改后重新启动项目
授权完成后未返回应用检查开发者门户中是否登记了当前环境使用的 Redirect URI
AI 检测到项目为纯前端 / 静态架构改读《使用生成式 AI 接入非机密客户端》《Python 最小可运行示例》;或引入可保管密钥的服务端后继续本页
UserInfo 没有 email令牌未含 email(用户取消或未申请);已授予时应始终有该字段。检查令牌响应中的 scope
头像 / 昵称不像真实资料未授权对应细项时 UserInfo 仍有字段,但是默认占位值(见《令牌与用户信息》);按 scope 判断是否为真实资料
email 形如隐私中继地址用户在同意页选择了隐私邮箱;按普通邮箱处理即可,勿索取真实邮箱

有关协议流程和参数的完整说明,请阅读《接入概述》《授权码与 PKCE》《令牌与用户信息》《权限与同意》《示例与排错》和《Python 最小可运行示例》;客户端注册见同目录《注册与配置》。