使用生成式 AI 接入机密客户端 开发人员
上次更新:2026年8月12日
使用生成式 AI 接入机密客户端
本文面向希望借助生成式 AI、以机密客户端接入 OAuth 2.1 / OpenID Connect(OIDC)登录的开发者。即使尚未系统学习相关协议,也可以按照本页步骤完成基础接入。
整个过程只需要四步:
- 把本页提供的提示词交给 AI。
- 将 AI 输出的 Redirect URI(重定向 URI)登记到摇月开发者门户的标识符向导(选机密客户端)。
- 将开发者门户生成的
client_id和client_secret配置为服务端环境变量。 - 启动应用并测试**“通过摇月 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 客户端中的回调端点。用户在摇月通行账户完成身份认证和授权确认后,授权服务器会将浏览器重定向至该地址,并携带授权响应,例如 code 和 state。
Redirect URI 通常对应 AI 在应用后端创建的回调路由,不是普通主页。该路由负责校验授权响应、换取令牌、创建应用会话,并将用户重定向至登录后的页面。
Redirect URI 通常由应用 Origin 和回调路径组成。Origin 包含 scheme、host 和 port,例如 https://app.example.com 或 http://127.0.0.1:3000。
应用 Origin + /auth/swaymoon/callback
例如:
| 使用场景 | 应用地址 | Redirect URI |
|---|---|---|
| 本地开发 | http://127.0.0.1:3000 | http://127.0.0.1:3000/auth/swaymoon/callback |
| 正式网站 | https://app.example.com | https://app.example.com/auth/swaymoon/callback |
请优先使用 AI 根据项目路由和运行端口输出的完整 Redirect URI,不要自行推测。
Redirect URI 的精确匹配要求
授权请求中的 redirect_uri 必须与开发者门户中的登记值逐字符一致。这项校验用于防止授权码被发送至未经登记的地址。以下差异均会被视为不同的 URI:
http://和https://不同;127.0.0.1和localhost不同;3000和3001端口不同;- 有无末尾
/也可能不同。
因此,请完整复制 AI 输出的 URI,不要手动修改。如果 AI 分别输出本地环境和生产环境的 URI,请在开发者门户中逐条登记。
在开发者门户填写
- 登录 摇月开发者门户。
- 进入标识符,点击 + 打开「注册应用标识符」向导。
- 描述:填写用户在同意页可识别的名称;有服务端时选择机密客户端。
- 图标:可用默认图标,或上传并裁剪后继续。
- 重定向 URI:粘贴 AI 给出的完整 Redirect URI(本地与生产可分别添加)。
- 功能:保持
openid必选。需要联系邮箱时再设置email(必选 / 可选 / 不申请);资料细项亦可选或必选(必选须填理由与隐私政策)。用户可能选择隐私邮箱,你方按普通email处理即可。详见《权限与同意》。 - 确认后点「注册」。
创建成功后,开发者门户会提示客户端凭证(请立即保存):
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 完成令牌交换。
第四步:测试登录
- 按照 AI 给出的命令启动项目。
- 打开包含登录按钮的页面。
- 选择**“通过摇月 Swaymoon 通行账户登录”**。
- 在摇月官方页面完成登录和授权。
- 浏览器返回你的应用,并显示已登录状态。
用户侧只需显示一个登录按钮。授权重定向、回调校验、令牌交换和应用会话创建均由服务端完成。
<a href="/auth/swaymoon">通过摇月 Swaymoon 通行账户登录</a>
实际按钮的组件实现和样式由 AI 根据当前项目生成,无需手动复制以上 HTML。
常见问题
可以将错误信息提供给 AI 辅助排查,但应先移除其中的客户端凭证、令牌和完整回调查询参数。不要发送包含 code= 或 state= 的完整浏览器地址。
| 问题 | 排查方式 |
|---|---|
| 提示 Redirect URI 不匹配 | 重新复制 AI 输出的完整 URI,并与开发者门户中的登记值逐字符比较 |
提示 invalid_client | 检查 client_id 和 client_secret 是否填在服务端环境变量中,修改后重新启动项目 |
| 授权完成后未返回应用 | 检查开发者门户中是否登记了当前环境使用的 Redirect URI |
| AI 检测到项目为纯前端 / 静态架构 | 改读《使用生成式 AI 接入非机密客户端》《Python 最小可运行示例》;或引入可保管密钥的服务端后继续本页 |
UserInfo 没有 email | 令牌未含 email(用户取消或未申请);已授予时应始终有该字段。检查令牌响应中的 scope |
| 头像 / 昵称不像真实资料 | 未授权对应细项时 UserInfo 仍有字段,但是默认占位值(见《令牌与用户信息》);按 scope 判断是否为真实资料 |
email 形如隐私中继地址 | 用户在同意页选择了隐私邮箱;按普通邮箱处理即可,勿索取真实邮箱 |
有关协议流程和参数的完整说明,请阅读《接入概述》《授权码与 PKCE》《令牌与用户信息》《权限与同意》《示例与排错》和《Python 最小可运行示例》;客户端注册见同目录《注册与配置》。