[{"data":1,"prerenderedAt":30},["ShallowReactive",2],{"doc:\u002Fcontracts\u002Foauth":3},{"title":4,"route":5,"toc":6,"segments":25,"source":29},"鲲 Galgame OAuth 文档","\u002Fcontracts\u002Foauth",[7,11,13,17,19,21,23],{"id":8,"text":9,"depth":10},"重要约定-身份操作必须在-oauth-完成","重要约定：身份操作必须在 OAuth 完成",2,{"id":12,"text":12,"depth":10},"文档索引",{"id":14,"text":15,"depth":16},"api-参考-按主题","API 参考（按主题）",3,{"id":18,"text":18,"depth":16},"完整接入指南",{"id":20,"text":20,"depth":10},"响应格式",{"id":22,"text":22,"depth":10},"认证",{"id":24,"text":24,"depth":10},"变更摘要",[26],{"type":27,"html":28},"html","\u003Ch1 id=\"鲲-galgame-oauth-文档\" tabindex=\"-1\">鲲 Galgame OAuth 文档\u003C\u002Fh1>\n\u003Cp>基础路径：\u003Ccode>\u002Fapi\u002Fv1\u003C\u002Fcode>\u003C\u002Fp>\n\u003Cdiv class=\"kun-table-wrap\">\u003Ctable>\u003Cthead>\n\u003Ctr>\n\u003Cth>环境\u003C\u002Fth>\n\u003Cth>Base URL\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>开发\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>http:\u002F\u002F127.0.0.1:9277\u002Fapi\u002Fv1\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>生产\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>https:\u002F\u002Foauth.kungal.com\u002Fapi\u002Fv1\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\u003C\u002Fdiv>\u003Ch2 id=\"重要约定-身份操作必须在-oauth-完成\" tabindex=\"-1\">重要约定：身份操作必须在 OAuth 完成\u003C\u002Fh2>\n\u003Cp>下游 kungal \u002F moyu \u002F wiki \u003Cstrong>不要在自己前端实现下列操作\u003C\u002Fstrong>：\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>新用户注册\u003C\u002Fstrong>（跳转到 \u003Ccode>oauth.kungal.com\u002Fauth\u002Fregister?redirect=&lt;oauth-authorize-url&gt;\u003C\u002Fcode>，注册成功后自动 SSO 回跳）—— 详见 \u003Ca href=\"\u002Fcontracts\u002Foauth\u002F05-registration\">05-registration.md\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Cstrong>改邮箱\u003C\u002Fstrong>（POST \u002Fauth\u002Femail\u002Fsend-code + PUT \u002Fauth\u002Femail）\u003C\u002Fli>\n\u003Cli>\u003Cstrong>改密码\u003C\u002Fstrong>（PUT \u002Fauth\u002Fpassword）\u003C\u002Fli>\n\u003Cli>重设密码 \u002F 启用 2FA \u002F 管理登录设备 \u002F 注销账号 \u002F 撤销已授权 OAuth Client（未来）\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>跳转目标：注册去 \u003Ccode>\u002Fauth\u002Fregister?redirect=...\u003C\u002Fcode>，账号管理去 \u003Ccode>https:\u002F\u002Foauth.kungal.com\u002Fprofile\u003C\u002Fcode>。\u003C\u002Fp>\n\u003Cp>技术上这些端点都能通过 end-user JWT 代理，但身份层操作\u003Cstrong>必须集中在一个前端\u003C\u002Fstrong>：安全审计单点、未来加 2FA \u002F 异地通知时只改一处、避免邮箱劫持攻击面跨多个站点放大。\u003C\u002Fp>\n\u003Cp>展示层操作（name \u002F avatar \u002F bio）可以站内提供 UI 或跳转，任选。\u003C\u002Fp>\n\u003Cp>详细分类表 + 跳转按钮代码示例见 \u003Ca href=\"\u002Fcontracts\u002Foauth\u002F02-user-profile#%E8%BA%AB%E4%BB%BD%E6%93%8D%E4%BD%9C-vs-%E5%B1%95%E7%A4%BA%E6%93%8D%E4%BD%9C\">02-user-profile.md §身份操作 vs 展示操作\u003C\u002Fa>。\u003C\u002Fp>\n\u003Chr>\n\u003Ch2 id=\"文档索引\" tabindex=\"-1\">文档索引\u003C\u002Fh2>\n\u003Ch3 id=\"api-参考-按主题\" tabindex=\"-1\">API 参考（按主题）\u003C\u002Fh3>\n\u003Cdiv class=\"kun-table-wrap\">\u003Ctable>\u003Cthead>\n\u003Ctr>\n\u003Cth>#\u003C\u002Fth>\n\u003Cth>文件\u003C\u002Fth>\n\u003Cth>内容\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>01\u003C\u002Ftd>\n\u003Ctd>\u003Ca href=\"\u002Fcontracts\u002Foauth\u002F01-oauth-endpoints\">oauth-endpoints.md\u003C\u002Fa>\u003C\u002Ftd>\n\u003Ctd>OAuth 2.0 协议端点：\u003Ccode>\u002Foauth\u002Ftoken\u003C\u002Fcode>、\u003Ccode>\u002Foauth\u002Fauthorize\u003C\u002Fcode>、\u003Ccode>\u002Foauth\u002Fuserinfo\u003C\u002Fcode>、\u003Ccode>\u002Foauth\u002Frevoke\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>02\u003C\u002Ftd>\n\u003Ctd>\u003Ca href=\"\u002Fcontracts\u002Foauth\u002F02-user-profile\">user-profile.md\u003C\u002Fa>\u003C\u002Ftd>\n\u003Ctd>用户自助：\u003Ccode>GET\u002FPATCH \u002Fauth\u002Fme\u003C\u002Fcode> + \u003Ccode>POST \u002Fauth\u002Fme\u002Favatar\u003C\u002Fcode>（含头像上传）\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>03\u003C\u002Ftd>\n\u003Ctd>\u003Ca href=\"\u002Fcontracts\u002Foauth\u002F03-cross-service\">cross-service.md\u003C\u002Fa>\u003C\u002Ftd>\n\u003Ctd>服务到服务：\u003Ccode>\u002Fusers\u002Fbatch\u003C\u002Fcode>、\u003Ccode>\u002Fusers\u002Fsearch\u003C\u002Fcode>（OAuth Client Basic Auth）\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>04\u003C\u002Ftd>\n\u003Ctd>\u003Ca href=\"\u002Fcontracts\u002Foauth\u002F04-tokens-and-errors\">tokens-and-errors.md\u003C\u002Fa>\u003C\u002Ftd>\n\u003Ctd>JWT Access Token claims + 完整错误码速查（OAuth 15xxx \u002F 认证 10xxx \u002F 通用）\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>05\u003C\u002Ftd>\n\u003Ctd>\u003Ca href=\"\u002Fcontracts\u002Foauth\u002F05-registration\">registration.md\u003C\u002Fa>\u003C\u002Ftd>\n\u003Ctd>用户注册流程：跳转 OAuth 注册 + 邮箱验证码 + 自动 SSO 回跳；\u003Ccode>POST \u002Fauth\u002Fregister\u002Fsend-code\u003C\u002Fcode> + \u003Ccode>POST \u002Fauth\u002Fregister\u003C\u002Fcode>、\u003Ccode>GET \u002Foauth\u002Fclient-info\u003C\u002Fcode>；下游 PKCE 跳转示例\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>06\u003C\u002Ftd>\n\u003Ctd>\u003Ca href=\"\u002Fcontracts\u002Foauth\u002F06-moemoepoint\">moemoepoint.md\u003C\u002Fa>\u003C\u002Ftd>\n\u003Ctd>\u003Cstrong>设计规范（精简版）\u003C\u002Fstrong>：萌萌点全站统一货币（单一真源在 OAuth）。可变余额列 + append-only 审计日志 + 幂等发放\u002F扣除 RPC + 迁移与下游接入；含&quot;刻意没做的&quot;清单（将来需要再升级）\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>07\u003C\u002Ftd>\n\u003Ctd>\u003Ca href=\"\u002Fcontracts\u002Foauth\u002F07-logout\">logout.md\u003C\u002Fa>\u003C\u002Ftd>\n\u003Ctd>\u003Cstrong>登出与单点登出（RP-Initiated Logout）\u003C\u002Fstrong>：修复「登出后再登录直接静默登回原账号」。RP 登出须顶层跳转 OP 登出入口 \u003Ccode>GET \u002Fauth\u002Flogout\u003C\u002Fcode>；含 \u003Ccode>GET \u002Foauth\u002Fpost-logout-redirect\u003C\u002Fcode> 白名单校验 + \u003Ccode>prompt=login\u003C\u002Fcode> 强制重登；下游接入步骤\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>08\u003C\u002Ftd>\n\u003Ctd>\u003Ca href=\"\u002Fcontracts\u002Foauth\u002F08-creator-applications\">creator-applications.md\u003C\u002Fa>\u003C\u002Ftd>\n\u003Ctd>\u003Cstrong>创作者申请（Creator-Role Application）\u003C\u002Fstrong>：申请 → 管理员审核 → 通过\u002F拒绝（可重申）的中央队列。\u003Ccode>POST \u002Fcreator\u002Fapplications\u003C\u002Fcode> + \u003Ccode>GET \u002Fcreator\u002Fapplications\u002Fme\u003C\u002Fcode>（用户）；资格门槛\u003Cstrong>下游自治\u003C\u002Fstrong>、角色授予归 OAuth；含「从未申请省略 \u003Ccode>data\u003C\u002Fcode>」契约 + 错误码 17001-17005 + 下游耦合点\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>09\u003C\u002Ftd>\n\u003Ctd>\u003Ca href=\"\u002Fcontracts\u002Foauth\u002F09-account-switching\">account-switching.md\u003C\u002Fa>\u003C\u002Ftd>\n\u003Ctd>✅ \u003Cstrong>账号切换（多账号 \u002F Account Switching）——后端 + OP 选择器已实现，下游可接入\u003C\u002Fstrong>：Gmail 式多账号 + 一键切换。会话袋在 OP；切换走 \u003Ccode>prompt=select_account\u003C\u002Fcode> + \u003Ccode>login_hint\u003C\u002Fcode> 重定向（同站可用 \u003Ccode>\u002Fauth\u002Fsessions\u003C\u002Fcode> JSON API）；全局活跃 = 焦点对齐（同 \u003Ccode>.kungal.com\u003C\u002Fcode> 瞬时 \u002F moyu 跨 TLD 对齐）；登出 = 撤销 + 短 TTL；管理员切入需重登（\u003Ccode>10016\u003C\u002Fcode>）。apps\u002Fweb + wiki 切换器已接入，forum\u002Fmoyu 待做。内部实现见 infra \u003Ccode>docs\u002Fauth\u002F02\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>10\u003C\u002Ftd>\n\u003Ctd>\u003Ca href=\"\u002Fcontracts\u002Foauth\u002F10-app-directory\">app-directory.md\u003C\u002Fa>\u003C\u002Ftd>\n\u003Ctd>🚧 \u003Cstrong>应用目录（生态一键登录 \u002F App Directory）\u003C\u002Fstrong>：注册\u002F登录时展示「拥有一个鲲 Galgame 账号即可一键登录以下网站」。每个 OAuth client 一个 opt-in \u003Ccode>listed\u003C\u002Fcode> 开关 + \u003Ccode>logo_url\u003C\u002Fcode>\u002F\u003Ccode>tagline\u003C\u002Fcode>\u002F\u003Ccode>display_order\u003C\u002Fcode>；公开只读 \u003Ccode>GET \u002Foauth\u002Fecosystem\u003C\u002Fcode> 返回 \u003Ccode>listed\u003C\u002Fcode> client 的展示字段；下游 modal \u002F OAuth 注册页展示「生态 strip」。对应业界 App Launcher 模式（无 OAuth 标准，属产品元数据）\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>11\u003C\u002Ftd>\n\u003Ctd>\u003Ca href=\"\u002Fcontracts\u002Foauth\u002F11-roles\">roles.md\u003C\u002Fa>\u003C\u002Ftd>\n\u003Ctd>⚖️ \u003Cstrong>角色与能力语义（权威定义，Tier A）\u003C\u002Fstrong>：全站五角色 \u003Ccode>user\u003C\u002Fcode>\u002F\u003Ccode>creator\u003C\u002Fcode>\u002F\u003Ccode>moderator\u003C\u002Fcode>\u002F\u003Ccode>admin\u003C\u002Fcode>\u002F\u003Ccode>ren\u003C\u002Fcode> 的唯一权威来源。\u003Ccode>roles\u003C\u002Fcode> claim = 角色名集合（普通用户为空数组，\u003Ccode>user\u003C\u002Fcode> 隐式）；管理轴逐级包含 \u003Ccode>moderator ⊂ admin ⊂ ren\u003C\u002Fcode>，\u003Ccode>creator\u003C\u002Fcode> 为正交的「直接发布」能力；\u003Cstrong>下游必须遵守的 MUST 规则\u003C\u002Fstrong> + 授予矩阵 + 当前 kungal\u002Fmoyu 对 \u003Ccode>ren\u003C\u002Fcode> 的合规差距（必须整改）\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>12\u003C\u002Ftd>\n\u003Ctd>\u003Ca href=\"\u002Fcontracts\u002Foauth\u002F12-site-roles\">site-roles.md\u003C\u002Fa>\u003C\u002Ftd>\n\u003Ctd>🧩 \u003Cstrong>站点域角色（site-scoped roles，权威定义，Tier A）\u003C\u002Fstrong>：让账号\u003Cstrong>只在某一个站点\u003C\u002Fstrong>持职（如「letmoe 的 moderator」），是 11 五角色契约的\u003Cstrong>加法扩展\u003C\u002Fstrong>（不改其语义）。\u003Ccode>site_roles\u003C\u002Fcode> claim = 按签发 client 站点定界的扁平角色名数组（access token \u002F userinfo \u002F \u003Ccode>\u002Fusers\u002Fbatch\u003C\u002Fcode> 三处出现）；下游\u003Cstrong>并入\u003C\u002Fstrong>既有角色集喂能力函数；名策略禁 \u003Ccode>user\u003C\u002Fcode>\u002F\u003Ccode>admin\u003C\u002Fcode>\u002F\u003Ccode>ren\u003C\u002Fcode>（安全不变量）+ 允许自定义捆名；授予\u002F撤销仅 OAuth 后台（\u003Ccode>admin\u003C\u002Fcode>\u002F\u003Ccode>ren\u003C\u002Fcode>）\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\u003C\u002Fdiv>\u003Ch3 id=\"完整接入指南\" tabindex=\"-1\">完整接入指南\u003C\u002Fh3>\n\u003Cdiv class=\"kun-table-wrap\">\u003Ctable>\u003Cthead>\n\u003Ctr>\n\u003Cth>文件\u003C\u002Fth>\n\u003Cth>内容\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ca href=\"\u002Fcontracts\u002Foauth\u002Foauth-integration-guide\">oauth-integration-guide.md\u003C\u002Fa>\u003C\u002Ftd>\n\u003Ctd>端到端 OAuth 接入走查：注册 client、PKCE、token 轮换、并发刷新、跨域 \u002F 跨站坑、安全注意事项\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ca href=\"\u002Fcontracts\u002Foauth\u002Fnuxt-integration-prompt\">nuxt-integration-prompt.md\u003C\u002Fa>\u003C\u002Ftd>\n\u003Ctd>Nuxt 3\u002F4 项目的快速上手指南（含 SSR 回调处理代码）\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\u003C\u002Fdiv>\u003Chr>\n\u003Ch2 id=\"响应格式\" tabindex=\"-1\">响应格式\u003C\u002Fh2>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Ccode class=\"language-json\">\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\">  \"code\"\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\">0\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">,        \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F 0 = 成功，非零 = 错误码\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\">  \"message\"\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">: \u003C\u002Fspan>\u003Cspan style=\"color:#032F62;--shiki-dark:#9ECBFF\">\"成功\"\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#005CC5;--shiki-dark:#79B8FF\">  \"data\"\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">: { \u003C\u002Fspan>\u003Cspan style=\"color:#B31D28;--shiki-light-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic\">...\u003C\u002Fspan>\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\"> }   \u003C\u002Fspan>\u003Cspan style=\"color:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F 成功时有数据；失败时一般为 null 或缺省\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#24292E;--shiki-dark:#E1E4E8\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>认证失败返回 HTTP 401 \u002F 403\u003C\u002Fstrong>：\u003Ccode>\u002Fauth\u002Fme\u003C\u002Fcode> \u002F \u003Ccode>\u002Fauth\u002F*\u003C\u002Fcode> 等受保护端点（protected 组，挂 \u003Ccode>middleware.Auth\u003C\u002Fcode>，见 \u003Ccode>cmd\u002Foauth\u002Fmain.go\u003C\u002Fcode>）在 token 缺失 \u002F 失效 \u002F 过期时返回 \u003Cstrong>HTTP 401\u003C\u002Fstrong> + \u003Ccode>{ code: 10001 | 10002 | 10003, message }\u003C\u002Fcode>；权限不足返回 \u003Cstrong>HTTP 403\u003C\u002Fstrong>。下游客户端应同时检查 HTTP status 与 \u003Ccode>code\u003C\u002Fcode>。完整列表见 \u003Ca href=\"\u002Fcontracts\u002Foauth\u002F04-tokens-and-errors#%E8%AE%A4%E8%AF%81%E9%94%99%E8%AF%AF-10xxx\">04-tokens-and-errors.md §认证错误\u003C\u002Fa>。\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Ch2 id=\"认证\" tabindex=\"-1\">认证\u003C\u002Fh2>\n\u003Cp>OAuth 一共有三种鉴权方式，按场景区分：\u003C\u002Fp>\n\u003Cdiv class=\"kun-table-wrap\">\u003Ctable>\u003Cthead>\n\u003Ctr>\n\u003Cth>方式\u003C\u002Fth>\n\u003Cth>用在哪\u003C\u002Fth>\n\u003Cth>谁有\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Cstrong>Bearer Token\u003C\u002Fstrong>（用户 JWT）\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>\u002Fauth\u002F*\u003C\u002Fcode> 用户自助 + \u003Ccode>\u002Foauth\u002Fuserinfo\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>已登录的终端用户\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Cstrong>OAuth Client Basic Auth\u003C\u002Fstrong>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>\u002Fusers\u002Fbatch\u003C\u002Fcode>、\u003Ccode>\u002Fusers\u002Fsearch\u003C\u002Fcode>（跨服务）\u003C\u002Ftd>\n\u003Ctd>已注册的 OAuth Client（kungal \u002F moyu \u002F wiki 等下游后端）\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Cstrong>Admin JWT\u003C\u002Fstrong>（Bearer + role=admin）\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>\u002Fadmin\u002F*\u003C\u002Fcode>（不在本文档范围）\u003C\u002Ftd>\n\u003Ctd>OAuth 后台管理员\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\u003C\u002Fdiv>\u003Cp>终端用户 JWT 通过完整的 OAuth Authorization Code + PKCE 流程拿到（详见 \u003Ca href=\"\u002Fcontracts\u002Foauth\u002Foauth-integration-guide\">oauth-integration-guide.md\u003C\u002Fa>）。Client Basic Auth 的 client_id \u002F client_secret 在 OAuth 后台创建 Client 时生成。\u003C\u002Fp>\n\u003Chr>\n\u003Ch2 id=\"变更摘要\" tabindex=\"-1\">变更摘要\u003C\u002Fh2>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>2026-06-27 角色语义定权威（重要）\u003C\u002Fstrong>：新增 \u003Ca href=\"\u002Fcontracts\u002Foauth\u002F11-roles\">11-roles.md\u003C\u002Fa>——把全站五角色 \u003Ccode>user\u003C\u002Fcode>\u002F\u003Ccode>creator\u003C\u002Fcode>\u002F\u003Ccode>moderator\u003C\u002Fcode>\u002F\u003Ccode>admin\u003C\u002Fcode>\u002F\u003Ccode>ren\u003C\u002Fcode> 及其能力语义定为 \u003Cstrong>Tier A 权威\u003C\u002Fstrong>，下游必须遵守。要点：① \u003Ccode>roles\u003C\u002Fcode> claim 是\u003Cstrong>角色名集合\u003C\u002Fstrong>，普通用户为\u003Cstrong>空数组\u003C\u002Fstrong>（\u003Ccode>user\u003C\u002Fcode> 隐式，下游不得用「数组含 \u003Ccode>user\u003C\u002Fcode>」判断登录）；② 管理轴\u003Cstrong>逐级包含\u003C\u002Fstrong> \u003Ccode>moderator ⊂ admin ⊂ ren\u003C\u002Fcode>，任何把 claim 映射成内部权限的逻辑必须让 \u003Ccode>ren ⊇ admin ⊇ moderator\u003C\u002Fcode>；③ \u003Ccode>creator\u003C\u002Fcode> 是\u003Cstrong>正交\u003C\u002Fstrong>的「直接发布 galgame」能力，不含审核\u002F管理权。\u003Cstrong>下游 kungal \u002F moyu 必须整改对 \u003Ccode>ren\u003C\u002Fcode> 的处理\u003C\u002Fstrong>：kungal 数值等级把 \u003Ccode>ren\u003C\u002Fcode> 塌成普通用户、moyu 完全不识别 \u003Ccode>ren\u003C\u002Fcode>——目前仅因「ren 账号必同时持 admin」未出事，违反健壮性要求，须修复（见 11 §6）。\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>2026-06-14 登出修复（RP-Initiated Logout）\u003C\u002Fstrong>：新增 \u003Ca href=\"\u002Fcontracts\u002Foauth\u002F07-logout\">07-logout.md\u003C\u002Fa>。修复「在 wiki \u002F 补丁站登出后，再点登录\u002F注册会静默登回刚才的账号」——根因是 RP 登出没清掉 OP（\u003Ccode>oauth.kungal.com\u003C\u002Fcode>）的会话（OP 的 \u003Ccode>localStorage\u003C\u002Fcode> 跨 origin 清不掉 + 跨站 cookie 带不过去）。方案：RP 登出时\u003Cstrong>顶层跳转\u003C\u002Fstrong>到 OP 登出入口 \u003Ccode>GET https:\u002F\u002Foauth.kungal.com\u002Fauth\u002Flogout?client_id=&amp;redirect=\u003C\u002Fcode>，由 OP 清会话再回跳。新增后端 \u003Ccode>GET \u002Foauth\u002Fpost-logout-redirect\u003C\u002Fcode> 白名单校验 + \u003Ccode>GET \u002Foauth\u002Fauthorize\u003C\u002Fcode> 的 \u003Ccode>prompt=login\u003C\u002Fcode> 参数。\u003Cstrong>下游 kungal \u002F moyu 必须改登出实现\u003C\u002Fstrong>（见 07）。\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>2026-05-23 注册流程统一（L1，重要）\u003C\u002Fstrong>：新增 \u003Ca href=\"\u002Fcontracts\u002Foauth\u002F05-registration\">05-registration.md\u003C\u002Fa> 文档；引入\u003Cstrong>邮箱验证码两步注册\u003C\u002Fstrong>——\u003Ccode>POST \u002Fauth\u002Fregister\u002Fsend-code\u003C\u002Fcode> 寄码 + \u003Ccode>POST \u002Fauth\u002Fregister\u003C\u002Fcode> 带 code 创建账号并发 token（\u003Cstrong>注册即登录\u003C\u002Fstrong>，返回 access_token + 写 refresh cookie）；新增 \u003Ca href=\"\u002Fcontracts\u002Foauth\u002F05-registration#get-oauthclient-info\">GET \u002Foauth\u002Fclient-info\u003C\u002Fa> 公开元数据端点；\u003Ccode>oauth_clients\u003C\u002Fcode> 加 \u003Ccode>auto_consent\u003C\u002Fcode> 列，5 个第一方 client 默认开启——同意页对第一方静默跳过，用户感知是&quot;注册完一闪回到原站点已登录&quot;。下游 kungal \u002F moyu 的 legacy 注册端点全部删除，&quot;注册&quot;按钮改为复用登录的 PKCE 跳转模式（目标 URL 换成 \u003Ccode>\u002Fauth\u002Fregister?redirect=&lt;authorize_url&gt;\u003C\u002Fcode>）。\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>2026-05-23 政策\u003C\u002Fstrong>：明确&quot;身份层 vs 展示层&quot;分类。下游禁止在自己前端做改邮箱 \u002F 改密码 \u002F 注销账号等身份操作，必须跳转 OAuth profile。详见上方&quot;重要约定&quot;小节和 \u003Ca href=\"\u002Fcontracts\u002Foauth\u002F02-user-profile#%E8%BA%AB%E4%BB%BD%E6%93%8D%E4%BD%9C-vs-%E5%B1%95%E7%A4%BA%E6%93%8D%E4%BD%9C\">02-user-profile.md\u003C\u002Fa>。\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>2026-05-23\u003C\u002Fstrong>：新增 \u003Ca href=\"\u002Fcontracts\u002Foauth\u002F02-user-profile#post-authmeavatar\">POST \u002Fauth\u002Fme\u002Favatar\u003C\u002Fa> 端点。一次性的&quot;上传头像图片 → 写库&quot; multipart 端点，\u003Cstrong>避免下游 kungal \u002F moyu 自己维护 image_service client\u003C\u002Fstrong>。配额从 OAuth 一侧扣；老的两步法（\u003Ccode>PATCH \u002Fauth\u002Fme { avatar_image_hash }\u003C\u002Fcode>）继续保留。\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>2026-05-23\u003C\u002Fstrong>：正式收录 \u003Ca href=\"\u002Fcontracts\u002Foauth\u002F02-user-profile#post-authemailsend-code\">POST \u002Fauth\u002Femail\u002Fsend-code\u003C\u002Fa> \u002F \u003Ca href=\"\u002Fcontracts\u002Foauth\u002F02-user-profile#put-authemail\">PUT \u002Fauth\u002Femail\u003C\u002Fa> \u002F \u003Ca href=\"\u002Fcontracts\u002Foauth\u002F02-user-profile#put-authpassword\">PUT \u002Fauth\u002Fpassword\u003C\u002Fa> 端点文档（以前只有口头提及）。同时把对应的错误码 10004 \u002F 10006 \u002F 10010-10013 补全到 \u003Ca href=\"\u002Fcontracts\u002Foauth\u002F04-tokens-and-errors#%E8%AE%A4%E8%AF%81%E9%94%99%E8%AF%AF-10xxx\">04-tokens-and-errors.md\u003C\u002Fa>。\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>文档拆分（2026-05-23）\u003C\u002Fstrong>：原 \u003Ccode>api-reference.md\u003C\u002Fcode> 拆为 4 个主题文件（01-04）。所有内容保留，按&quot;OAuth 协议 \u002F 用户自助 \u002F 跨服务 \u002F Token 与错误&quot;四块组织。完整 OAuth 接入指南仍是单独的 \u003Ca href=\"\u002Fcontracts\u002Foauth\u002Foauth-integration-guide\">oauth-integration-guide.md\u003C\u002Fa>。\u003C\u002Fp>\n\u003C\u002Fblockquote>\n","kun-galgame-infra\u002Fdocs\u002Fintegration\u002Foauth\u002FREADME.md",1783514297253]