Skip to content

Server API ​

与 Web 端接口的区别 ​

维度Web 端接口Server API
路径前缀/api/auth、/api/tickets、/api/admin/* 等/api/mc/*
认证方式Authorization: Bearer <accessToken>(JWT)X-Server-Key: <apiKey>,玩家级接口另加 X-Player-Session
身份来源登录用户本人key 绑定的服务器以及会话对应的 API 账号
服务器上下文无由 key 的绑定关系或请求体 serverId 解析得出
玩家写操作用户本人操作须持有有效的 player session
实时链路—Socket.IO 的 /mc 命名空间,见 WebSocket 连接

两类接口的成功响应与错误响应均封装在统一的 envelope 中:

jsonc
// 成功
{
  "success": true,    // boolean,成功时为 true
  "data": {}          // object,业务数据,各接口的 data 结构见对应页面
}

失败时返回:

jsonc
// 403
{
  "success": false,   // boolean,失败时为 false
  "statusCode": 403,  // number,HTTP 状态码
  "message": "Minecraft player session does not match requested UUID" // string,错误文案
}

204 No Content 无响应体。本组其余页面的响应示例仅列 envelope 中 data 的内容,实际响应将在此之外再封装一层。

基址与路径 ​

  • baseUrl 为站点公开 origin,例如 https://tickets.example.com,不带 /api,也不带尾斜杠。
  • HTTP 接口均为 ${baseUrl}/api/mc/...,由后端 backend/src/routes/mc.ts 统一挂载。
  • 实时通道为 ${baseUrl}/socket.io,namespace 使用 /mc,握手使用 auth.serverKey,不使用请求头。
  • Docker 部署仅需公开 Web 容器,由 Web 容器将这两类流量转发到内部后端。
http
POST /api/mc/session HTTP/1.1
Host: tickets.example.com
X-Server-Key: <apiKey>
Content-Type: application/json
jsonc
{
  "minecraftUuid": "<uuid>",                // string,必填,合法 UUID
  "playerCredential": "<playerCredential>"  // string,必填,绑定阶段下发的凭证
}

认证模型 ​

server key 类型 ​

key 的类型定义在 backend/src/constants/server-api-key.ts,仅两种,绑定关系决定请求定位服务器的方式:

类型取值绑定请求要求
Paper/Foliapaper_folia恰好一台服务器直接采用绑定的服务器,body 不要求 serverId
Velocityvelocity可绑定多台服务器每个请求的 JSON body 须带 serverId

Velocity 的 serverId 为该服务器在服务器管理中的识别 ID;识别 ID 未设置时回退为服务器 ID。该值须与 Velocity 注册的后端服务器名一致,否则请求将被拒绝:

jsonc
{
  "serverId": "survival"  // string,Velocity 必填,服务器识别 ID,须与 Velocity 注册的后端服务器名一致
}

serverId 缺失返回 401(请求体缺少 serverId),key 未授权该服务器同样返回 401(该 API Key 未授权此服务器)。服务器解析先于玩家会话校验执行,因此 /api/mc/* 的每个请求均先定位到唯一一台服务器。

玩家 session ​

玩家级接口要求 X-Player-Session: <sessionToken>,token 由 POST /api/mc/session 以绑定阶段下发的 playerCredential 换取,有效期为 5 分钟(MINECRAFT_PLAYER_SESSION_TTL_MS,见 backend/src/constants/minecraft-session.ts)。

会话记录保存签发时解析出的服务器;后续请求解析到另一台服务器时,会话失效并返回 401。后端按会话对应 API 账号的实时角色执行权限判断,不信任请求体中的 UUID,也不信任插件本地的角色缓存。

议题读取类接口采用条件鉴权:未携带会话时按匿名访客返回公开议题;管理后台开启「要求登录」后,匿名读取直接返回 401。写接口一律要求会话。

不要求玩家 session 的端点 ​

端点原因
POST /api/mc/register-link注册前尚无账号
POST /api/mc/link-code绑定前尚无账号
POST /api/mc/session该端点即签发会话
POST /api/mc/unlink固定拒绝,解绑仅在 Web 端进行
POST /api/mc/player-group/items上报玩家组名单,仅依赖 key
GET /api/templates、GET /api/templates/:name全局模板,不属于 /api/mc,见 其他接口与集成注意

错误与限流 ​

所有请求先经过按 IP 的 global 限流(默认 100 次/60 秒)。挂载 auth 限流的 MC 端点仅三个,默认 10 次/60 秒,可在管理后台调整:

端点额外限流
POST /api/mc/register-linkauth
POST /api/mc/link-codeauth
POST /api/mc/player-group/itemsauth
其余 /api/mc/* 端点仅 global

超限返回 429 与 请求过于频繁,请稍后再试,响应头包含 RateLimit-Limit、RateLimit-Remaining、RateLimit-Reset 和 Retry-After(秒)。

插件须配合处理以下两处 fail-closed 行为:

  1. 站点地址(管理后台 siteUrl)未配置或不合法时,POST /api/mc/register-link 返回 400,不从请求头推导地址,也不生成链接。
  2. 旧版插件或无 playerCredential 的历史绑定调用玩家级接口一律失败,须由用户在 Web 端解绑后重新绑定。

端点总表 ​

方法路径玩家 session说明
POST/api/mc/register-link否生成一次性注册链接,见 注册、绑定与会话
POST/api/mc/link-code否生成绑定码
POST/api/mc/session否以 credential 换取 5 分钟会话
POST/api/mc/unlink否固定返回 403
POST/api/mc/player-group/items否上报玩家名到玩家组,见 其他接口与集成注意
POST/api/mc/tickets必需游戏内创建议题,见 议题与评论
GET/api/mc/tickets可选议题列表(query 参数)
POST/api/mc/tickets/search可选议题列表(body 变体,供 Velocity 使用)
GET/api/mc/tickets/:uuid可选上一版本兼容的列表路径
GET/api/mc/tickets/:id/detail可选议题详情
POST/api/mc/tickets/:id/detail可选议题详情(body 变体)
GET/api/mc/tickets/:id/comments可选评论列表
POST/api/mc/tickets/:id/comments/list可选评论列表(body 变体)
GET/api/mc/user/:uuid必需当前绑定的用户信息
POST/api/mc/user必需当前绑定的用户信息(body 变体)
POST/api/mc/comments必需发表评论
POST/api/mc/tickets/:id/status必需变更状态
POST/api/mc/tickets/:id/close必需关闭议题
POST/api/mc/tickets/:id/reopen必需重新打开议题
GET/api/templates否模板列表(key 认证,非 /api/mc)
GET/api/templates/:name否模板详情(key 认证,非 /api/mc)

索引我维护的项目、服务与文档。