12 KiB
API Overview / API 总览
中文
页面作用
本页描述 accounts.svc.plus 当前 HTTP 面的总边界:
- 路由族如何划分。
- 每组路由由哪些
api/*.go文件拥有。 - 认证链路如何叠加。
- 成功与失败响应的公共形状是什么。
参数、返回体字段和逐接口依赖关系请继续阅读:
基础路由族
| 路由族 | 典型路径 | 主要 owner file | 说明 |
|---|---|---|---|
| 健康与版本 | GET /healthz GET /api/ping |
api/api.go |
活性检查与运行时镜像版本信息。 |
| 公共认证入口 | /api/auth/register /api/auth/login /api/auth/oauth/* |
api/api.go |
注册、登录、邮箱校验、OAuth 跳转、JWT refresh。 |
| 会话保护认证面 | /api/auth/session /api/auth/xworkmate/* /api/auth/subscriptions |
api/api.go api/xworkmate.go api/config_sync.go api/stripe.go |
以 session token 为主路径的控制面接口。 |
| Auth 作用域下的管理员接口 | /api/auth/admin/* |
api/admin_users_metrics.go api/admin_users.go api/admin_sandbox.go api/admin_assume.go api/homepage_video.go |
给 dashboard / BFF 使用的管理员接口。 |
公共 /api/admin/* 管理面 |
/api/admin/users/metrics /api/admin/traffic/* |
api/admin_users_metrics.go api/admin_agents.go api/accounting.go |
与前端约定的管理员根路径。 |
| 内部服务接口 | /api/internal/* |
api/internal_public_overview.go api/internal_sandbox_guest.go api/internal_network_identities.go api/accounting.go |
仅供受信任服务调用,走 internal service token。 |
| Agent 控制接口 | /api/agent-server/v1/* |
api/agent_server.go api/user_agents.go |
给 agent 或用户控制台提供节点与客户端视图。 |
| 账户读面 | /api/account/* |
api/accounting.go |
使用量、账单、策略快照读取。 |
| Legacy alias | /api/agent/nodes |
api/user_agents.go |
旧路径别名,规范路径是 /api/agent-server/v1/nodes。 |
认证模型
1. Session first
当前控制面的主事实来源是 API 进程内 session store:
- 登录、邮箱验证成功、密码重置确认成功、OAuth callback 都会签发 session token。
- token 同时通过响应体字段
token返回,并通过xc_sessioncookie 下发。 - 多数业务 handler 最终都调用
handler.lookupSession/handler.requireAuthenticatedUser做真实鉴权。
2. Optional JWT middleware
RegisterRoutes 只在 tokenService != nil 时给 /api/auth 的保护组和 /api/admin 组叠加:
auth.TokenService.AuthMiddleware()auth.RequireActiveUser(h.store)
因此真实行为是:
- 当
auth.enable关闭时,业务仍按 session 主路径工作。 - 当
auth.enable打开时,部分路由会先经过 JWT middleware,然后在 handler 内继续读取 session。 - 这就是为什么文档统一把当前模式描述为“session-first, JWT-optional”。
3. Internal service token
/api/internal/* 统一使用 auth.InternalAuthMiddleware():
- 读取
Authorization: Bearer <token> - 与环境变量
INTERNAL_SERVICE_TOKEN比较 - 失败时直接返回简化错误 JSON
4. Agent token
/api/agent-server/v1/users 与 /api/agent-server/v1/status 走 agentserver.Registry.Authenticate:
- 读取
Authorization: Bearer <agent-token> - 允许共享 token +
X-Agent-ID/agentId解析具体节点身份 - 认证成功后进入
Registry与store.NodeHealthSnapshot更新链路
响应约定
| 类别 | 典型形状 | 说明 |
|---|---|---|
| 通用成功 | {"message": "...", ...} 或领域对象 JSON |
大多数 handler 直接输出业务对象,不包统一 envelope。 |
| 会话成功 | {"token": "...", "expiresAt": "...", "user": {...}} |
登录、邮箱验证、密码重置确认、MFA 完成等都会返回 session 信息。 |
| 通用失败 | {"error":"code","message":"..."} |
由 respondError 统一组装,是最常见错误形状。 |
| 简化失败 | {"error":"..."} |
多见于 agent/internal/simple GORM handlers。 |
| Agent DTO | agentproto.ClientListResponse、204 No Content |
/users 返回结构化 DTO,/status 成功时无响应体。 |
关键 handler owner map
| 文件 | 负责的接口面 |
|---|---|
api/api.go |
注册、登录、session、OAuth、MFA、订阅、权限矩阵、/healthz、/api/ping。 |
api/xworkmate.go |
XWorkmate profile、secret locator、Vault-backed secret 读写、tenant bootstrap。 |
api/config_sync.go |
/api/auth/sync/config 与 /api/auth/sync/ack。 |
api/stripe.go |
Stripe checkout、portal、webhook。 |
api/admin_users_metrics.go |
/api/admin/* 路由注册、用户指标权限控制。 |
api/admin_users.go |
创建用户、暂停/恢复、删除、renew uuid、黑名单。 |
api/admin_agents.go |
管理面 agent 状态聚合。 |
api/accounting.go |
/api/account/*、/api/admin/traffic/*、内部策略与心跳。 |
api/agent_server.go |
Agent 拉取 client 列表、上报状态。 |
api/user_agents.go |
用户/控制台读取节点列表,含 sandbox 特判。 |
api/homepage_video.go |
公共首页视频与管理员首页视频配置。 |
api/admin_sandbox.go |
Sandbox binding 读写。 |
api/admin_assume.go |
Root 假扮 sandbox 会话。 |
api/internal_* |
内部 public overview、sandbox guest、network identities。 |
当前实现注意点
/api/auth/password/reset与/api/auth/password/reset/confirm被挂在 authProtected 组下,但核心业务逻辑本身仍是邮箱 / token 驱动;启用 JWT middleware 后会多一层前置校验。/api/auth/sandbox/binding既接受正常会话,也接受内部服务 token,因为 Console Guest/Demo 需要在无本地浏览器状态时读取绑定信息。/api/agent-server/v1/nodes没有挂在 token middleware 下,而是在 handler 内自行解析 session 或内部服务身份。/api/ping的version、commit、tag来自运行时IMAGE环境变量解析结果,而不是 Git 本地状态。
English
What This Page Covers
This page defines the current HTTP surface of accounts.svc.plus:
- how route families are split,
- which
api/*.gofiles own them, - how authentication layers stack,
- and what the shared success / error shapes look like.
For endpoint-level parameters, response fields, and dependency wiring, continue with:
Route Families
| Route family | Example paths | Main owner files | Purpose |
|---|---|---|---|
| Health and version | GET /healthz, GET /api/ping |
api/api.go |
Liveness and runtime image-derived version metadata. |
| Public auth entrypoints | /api/auth/register, /api/auth/login, /api/auth/oauth/* |
api/api.go |
Registration, login, email verification, OAuth redirects, JWT refresh. |
| Session-protected auth surface | /api/auth/session, /api/auth/xworkmate/*, /api/auth/subscriptions |
api/api.go, api/xworkmate.go, api/config_sync.go, api/stripe.go |
Primary control-plane APIs built around session tokens. |
| Auth-scoped admin APIs | /api/auth/admin/* |
api/admin_users_metrics.go, api/admin_users.go, api/admin_sandbox.go, api/admin_assume.go, api/homepage_video.go |
Admin APIs used by the dashboard / BFF. |
Public /api/admin/* admin root |
/api/admin/users/metrics, /api/admin/traffic/* |
api/admin_users_metrics.go, api/admin_agents.go, api/accounting.go |
Frontend-facing admin root path. |
| Internal service APIs | /api/internal/* |
api/internal_public_overview.go, api/internal_sandbox_guest.go, api/internal_network_identities.go, api/accounting.go |
Trusted service-to-service APIs protected by the internal service token. |
| Agent control APIs | /api/agent-server/v1/* |
api/agent_server.go, api/user_agents.go |
Node and client views for agents and the control console. |
| Account read models | /api/account/* |
api/accounting.go |
Usage, billing, and policy snapshot reads. |
| Legacy alias | /api/agent/nodes |
api/user_agents.go |
Backward-compatible alias for /api/agent-server/v1/nodes. |
Authentication Model
1. Session-first
The primary control-plane fact source is the process-local session store:
- login, email verification success, password reset confirmation, and OAuth callback all issue a session token,
- the token is returned in the body as
tokenand also set as thexc_sessioncookie, - most business handlers ultimately call
handler.lookupSessionorhandler.requireAuthenticatedUser.
2. Optional JWT middleware
RegisterRoutes adds these middlewares to the protected /api/auth group and the /api/admin root only when tokenService != nil:
auth.TokenService.AuthMiddleware()auth.RequireActiveUser(h.store)
So the actual runtime behavior is:
- when
auth.enableis off, business routes still work through the session-centric path, - when
auth.enableis on, some routes first pass JWT middleware and then still load the session in the handler, - which is why the current system should be described as session-first and JWT-optional.
3. Internal service token
/api/internal/* is guarded by auth.InternalAuthMiddleware():
- it reads
Authorization: Bearer <token>, - compares it to
INTERNAL_SERVICE_TOKEN, - and returns simplified JSON errors on failure.
4. Agent token
/api/agent-server/v1/users and /api/agent-server/v1/status authenticate through agentserver.Registry.Authenticate:
- they read
Authorization: Bearer <agent-token>, - support shared tokens plus
X-Agent-ID/agentIdto resolve the concrete node, - and then enter the registry and node-health persistence pipeline.
Response Conventions
| Category | Typical shape | Notes |
|---|---|---|
| Generic success | {"message": "...", ...} or a domain object |
Most handlers return domain JSON directly instead of a global envelope. |
| Session success | {"token": "...", "expiresAt": "...", "user": {...}} |
Returned by login, email verification, password reset confirmation, MFA completion, and similar flows. |
| Standard failure | {"error":"code","message":"..."} |
Produced by respondError; this is the most common error envelope. |
| Simplified failure | {"error":"..."} |
Common in internal / agent / simple GORM-backed handlers. |
| Agent DTOs | agentproto.ClientListResponse, 204 No Content |
/users returns a typed DTO, while /status returns no body on success. |
Handler Ownership Map
| File | Owned API surface |
|---|---|
api/api.go |
Registration, login, session, OAuth, MFA, subscriptions, permission matrix, /healthz, /api/ping. |
api/xworkmate.go |
XWorkmate profile, secret locator metadata, Vault-backed secret mutation, tenant bootstrap. |
api/config_sync.go |
/api/auth/sync/config and /api/auth/sync/ack. |
api/stripe.go |
Stripe checkout, portal, and webhook handling. |
api/admin_users_metrics.go |
/api/admin/* route registration plus metrics permission guards. |
api/admin_users.go |
User creation, pause/resume, delete, renew UUID, blacklist operations. |
api/admin_agents.go |
Aggregated admin agent status view. |
api/accounting.go |
/api/account/*, /api/admin/traffic/*, internal policy reads, node heartbeat ingest. |
api/agent_server.go |
Agent client-list reads and status reports. |
api/user_agents.go |
User / console node list reads, including sandbox-specific behavior. |
api/homepage_video.go |
Public homepage video reads plus admin homepage video settings. |
api/admin_sandbox.go |
Sandbox binding reads and writes. |
api/admin_assume.go |
Root-only sandbox assume session flow. |
api/internal_* |
Internal public overview, sandbox guest, and network identity reads. |
Important Current Behaviors
/api/auth/password/resetand/api/auth/password/reset/confirmare mounted under the protected auth group even though their business logic is email / reset-token driven; enabling JWT middleware adds an extra precondition./api/auth/sandbox/bindingaccepts either a normal session or the internal service token because the Console Guest/Demo flow must read binding state without relying on browser-local state./api/agent-server/v1/nodesis intentionally outside token middleware and resolves sessions or trusted internal-service identity inside the handler./api/pingderivesversion,commit, andtagfrom the runtimeIMAGEenvironment variable, not from local Git state.