Base Account / Integration
账号系统接入文档
按能力模块拆分的接入规范,供产品工程和 AI Agent 按需获取。
Machine Readable Spec
AI Agent 可直接读取下方 JSON 进行自动接入。结构版本字段为 docVersion。 包含认证系统和邀请码系统的完整规范。
展开查看 Machine Readable JSON
{
"docVersion": "2026-03-06.3",
"generatedAt": "2026-03-06.3",
"service": "base-account-auth",
"issuer": "https://user.stringzhao.life",
"audience": "base-account-client",
"jwksUrl": "https://user.stringzhao.life/.well-known/jwks.json",
"authorizeContract": {
"entryPath": "/authorize",
"requiredQuery": [
"return_to",
"state"
],
"optionalQuery": [
"service (deprecated)"
],
"callbackQuery": [
"authorized",
"state"
]
},
"endpoints": [
{
"method": "GET",
"path": "/authorize",
"auth": "none",
"purpose": "统一授权入口。后端基于 return_to 的 origin 识别服务,未登录跳转登录页,已登录则按 consent 状态决定是否直接回跳。可选参数 prompt=select_account:即使已授权,也强制显示账号选择界面(用于多账号切换场景)。",
"errors": [
"400 invalid_authorize_request",
"400 invalid_return_to",
"400 invalid_service",
"400 invalid_state"
]
},
{
"method": "POST",
"path": "/api/auth/send-code",
"auth": "none",
"purpose": "发送邮箱验证码,返回 requestId。",
"errors": [
"400 invalid_input",
"429 rate_limited",
"502 email_delivery_failed"
]
},
{
"method": "POST",
"path": "/api/auth/verify-code",
"auth": "none",
"purpose": "校验验证码并签发 access/refresh token(同时写入 cookie)。",
"errors": [
"400 invalid_code",
"429 too_many_attempts",
"403 account_disabled"
]
},
{
"method": "POST",
"path": "/api/auth/authorize/approve",
"auth": "access_token",
"purpose": "用户在首次授权页点击同意后写入 consent 记录并返回回跳地址。",
"errors": [
"401 missing_access_token",
"400 invalid_input",
"400 invalid_return_to",
"400 invalid_service"
]
},
{
"method": "POST",
"path": "/api/auth/refresh",
"auth": "refresh_token",
"purpose": "刷新 access token 和 refresh token。",
"errors": [
"401 invalid_refresh_token",
"400 missing_refresh_token"
]
},
{
"method": "POST",
"path": "/api/auth/logout",
"auth": "refresh_token",
"purpose": "注销当前会话并清理 cookie。",
"errors": [
"200 幂等,refresh token 失效也可安全调用"
]
},
{
"method": "GET",
"path": "/api/auth/me",
"auth": "access_token",
"purpose": "获取当前 access token 对应用户信息。",
"errors": [
"401 missing_access_token",
"401 invalid_access_token"
]
},
{
"method": "GET",
"path": "/.well-known/jwks.json",
"auth": "none",
"purpose": "下游服务用于验证 JWT 的公钥集合。",
"errors": [
"必须公网可访问,且与 AUTH_ISSUER 保持同源策略"
]
}
],
"integrationSteps": [
{
"title": "准备环境变量",
"detail": "下游服务至少配置 AUTH_ISSUER、AUTH_AUDIENCE、AUTH_JWKS_URL;账号中心配置 AUTH_ALLOWED_RETURN_ORIGINS、AUTH_ALLOWED_RETURN_SUFFIXES。"
},
{
"title": "接入统一授权入口",
"detail": "外部服务统一跳转 /authorize?return_to&state(service 可传但会被忽略),禁止直接跳 /login。"
},
{
"title": "登记服务域名",
"detail": "推荐通过 CLI 注册服务:ba admin services create --origin https://your-app.example.com(也可在 Admin Console 的 Services 区域手动登记)。需先登记/启用 origin,再让外部服务发起授权。"
},
{
"title": "处理回跳并建立应用会话",
"detail": "回跳后在服务端读取共享 access_token cookie 验签 JWT,提取用户 email,然后创建应用自有的 gateway session cookie(HMAC 签名的 email + 过期时间)。重要:不要直接依赖共享 access_token cookie 作为日常登录态,否则跨应用切换账号会导致身份污染。"
},
{
"title": "按需接入 JWT 校验",
"detail": "如果你的服务需要在后端验签 access token,再接入 auth-sdk 的 JWKS 验签。"
}
],
"templates": [
{
"id": "node-middleware",
"title": "Node / Express 鉴权中间件",
"runtime": "Node 20+ / Express"
},
{
"id": "next-route-handler",
"title": "Next.js Route Handler 保护接口",
"runtime": "Next.js App Router"
},
{
"id": "frontend-login-flow",
"title": "前端最小登录流程",
"runtime": "Browser / SPA"
},
{
"id": "frontend-authorize-entry",
"title": "外部服务统一授权入口",
"runtime": "Browser / Web App"
},
{
"id": "frontend-authorize-callback",
"title": "回跳校验 + 获取用户态(简易版)",
"runtime": "Browser / Web App"
},
{
"id": "next-gateway-session",
"title": "Next.js Gateway Session 模式(推荐)",
"runtime": "Next.js App Router"
},
{
"id": "account-switching",
"title": "账号切换(多账号场景)",
"runtime": "Browser / Web App"
}
],
"checklist": [
"AUTH_ISSUER 与账号服务域名保持一致(当前: https://user.stringzhao.life)。",
"AUTH_AUDIENCE 在账号服务和下游服务严格一致(当前: base-account-client)。",
"AUTH_JWKS_URL 配置为 https://user.stringzhao.life/.well-known/jwks.json。",
"新接入服务需要先登记并启用 origin。推荐使用 CLI:ba admin services create --origin <url>(也可在 Admin Console -> Services 手动操作)。",
"/authorize 的 service 参数已弃用(兼容保留,但后端不再依赖该参数判定服务)。",
"AUTH_ALLOWED_RETURN_ORIGINS 建议至少包含 http://localhost:3000, https://user.stringzhao.life, https://stringzhao.life。",
"AUTH_ALLOWED_RETURN_SUFFIXES 建议配置为 .stringzhao.life,.vercel.app(一次覆盖你全部 Vercel 服务)。",
"外部服务统一从 /authorize 进入登录授权流程,不直接拼接 /login。",
"业务接口对 401/403/429 做显式处理,不把鉴权失败当系统异常。",
"access_token / refresh_token cookie 在 .stringzhao.life 域共享,任一子域的登录/切换会覆盖所有子域的登录态。接入方应创建应用自有的 gateway session cookie(参考模板),避免跨应用账号污染。",
"上线后至少做一次 send-code / verify-code / me 全链路回归。"
],
"externalIntegrationChecklist": [
"授权入口统一改为 /authorize?return_to=<absolute_url>&state=<opaque_state>。",
"service 参数可传可不传(兼容保留),但不能再用于服务身份判定。",
"发起授权前生成并持久化 state(建议 randomUUID + sessionStorage)。",
"回跳后必须校验 authorized=1 且 returned state 与本地 state 完全一致。",
"每个业务回跳域名(return_to origin)需先开通并启用。推荐使用 CLI:ba admin services create --origin <url>(也可在 /admin -> Services 手动操作)。",
"回跳后在服务端读取共享 access_token cookie 并验签 JWT(避免前端 CORS),然后创建应用自有的 gateway session cookie 作为日常登录态。不建议直接依赖共享 access_token cookie(跨应用账号污染风险)。",
"后端 JWT 验签配置保持一致:AUTH_ISSUER、AUTH_AUDIENCE、AUTH_JWKS_URL。",
"业务侧显式处理 400 invalid_service / 400 invalid_return_to / 401 invalid_access_token。",
"上线前至少完成首次授权、重复授权直跳、停用服务拦截、icon 展示回退四项回归。",
"如需账号切换功能,跳转 /authorize 时附加 prompt=select_account 参数。已授权用户将看到账号选择界面,可选择当前账号、历史登录账号或登录新账号。"
],
"invitationCodes": {
"description": "邀请码系统:每用户每应用可生成 N 个一次性邀请码,兑换后记录邀请关系。",
"defaultQuota": 3,
"endpoints": [
{
"method": "POST",
"path": "/api/auth/invitation-codes/generate",
"auth": "access_token",
"purpose": "为当前用户在指定应用下生成一个一次性邀请码。每用户每应用有配额限制(普通用户默认 3,管理员 1000)。serviceKey 需先通过 CLI 注册:ba admin services create --origin <url>。",
"errors": [
"401 missing_access_token",
"400 invalid_input",
"400 invalid_service",
"403 invitation_quota_exceeded"
]
},
{
"method": "POST",
"path": "/api/auth/invitation-codes/redeem",
"auth": "access_token",
"purpose": "兑换邀请码。仅需传入 code,无需 serviceKey(系统自动从邀请码记录中读取)。一次性使用,兑换后记录邀请关系(谁邀请了谁)。普通用户不能兑换自己生成的邀请码;管理员账号可用于自助开通。服务代理模式:使用 API key 认证时可传入 userId 代表终端用户兑换,适用于下游服务有独立 session 的场景。",
"errors": [
"401 missing_access_token",
"400 invalid_invitation_code",
"400 self_redeem_not_allowed",
"409 invitation_code_already_redeemed"
]
},
{
"method": "POST",
"path": "/api/auth/invitation-codes/validate",
"auth": "access_token",
"purpose": "仅校验邀请码有效性,不消费。仅需传入 code,无需 serviceKey。适用于前端实时校验场景。",
"errors": [
"401 missing_access_token",
"400 invalid_input"
]
},
{
"method": "GET",
"path": "/api/auth/invitation-codes?serviceKey=my-app",
"auth": "access_token",
"purpose": "列出当前用户在指定应用下生成的所有邀请码及配额信息。",
"errors": [
"401 missing_access_token",
"400 invalid_input"
]
},
{
"method": "POST",
"path": "/api/auth/invitation-codes/revoke",
"auth": "access_token",
"purpose": "撤销自己生成的 ACTIVE 状态邀请码。已兑换的码不可撤销。",
"errors": [
"401 missing_access_token",
"404 invitation_code_not_found",
"403 forbidden",
"400 invalid_invitation_code"
]
}
],
"integrationSteps": [
{
"title": "生成邀请码",
"detail": "已登录用户调用 POST /api/auth/invitation-codes/generate,传入 serviceKey,获得 8 位邀请码。每用户每应用默认可生成 3 个(管理员配额为 1000)。serviceKey 需先通过 CLI 注册服务:ba admin services create --origin https://your-app.example.com。"
},
{
"title": "分享邀请码",
"detail": "将邀请码通过任意渠道(聊天、邮件、社交媒体等)发送给受邀人。"
},
{
"title": "受邀人兑换",
"detail": "受邀人登录后调用 POST /api/auth/invitation-codes/redeem,仅需传入 code(不需要 serviceKey)。系统自动从邀请码记录中读取 serviceKey,记录邀请关系并返回 serviceKey 和邀请者 ID。"
},
{
"title": "下游业务处理",
"detail": "下游服务根据 redeem 返回的 serviceKey + creatorId 决定后续动作(如:解锁功能、发放奖励、建立推荐关系等)。"
}
]
}
}