文档 9.6.24
API 与凭证
遵循已安装集成的认证方式。桥接是操作队列,不是通用 SQL 接口。
分离权限#
服务器许可证、用户权限和上传令牌用途不同。上传令牌会过期,仅用于证据上传,不能管理面板。
处理错误#
认证失败、超时或限流时避免快速重试。结果不明的财务写入不要自动重复。不要在 URL、客户端或日志暴露认证头。
匹配接口、凭据与权限#
没有通用万能密钥。服务器许可证认证 SaaS 桥接,组件 API token 可能要求特定权限范围。浏览器管理操作需要登录账户角色、权限和相关 CSRF 校验。证据上传 token 限定上下文、服务器和请求,不是管理 token。
示例仅展示请求头,占位值不是真实凭据。协议内容由资源生成,任意 JSON 加这些头不会成为有效任务。认证信息应仅在服务器通信中使用,不要放在浏览器、URL、分析统计或共享错误中。
Authorization: Bearer YOUR_SERVER_LICENSE
Content-Type: application/json区分 HTTP 与任务结果#
桥接接受 POST JSON,不接受任意 SQL 或表名。pending/claimed 仍在进行,应先核对最终结果再显示成功。
- 401:核对目标服务器许可证是否已重新生成。
- 403 bridge_disabled / subscription_inactive / permission_denied:检查服务器的 Tosun Connect 卡片(bridge_disabled 表示连接已在那里关闭)、订阅和权限;重试不会获得权限。
- 405 / 415:修正方法和 JSON Content-Type;不能不断重发错误 JSON。
- 429:遵守 Retry-After 并等待;桥接限制并发,失败后增加延时。
- 503 / timeout:记录脱敏时间与请求标识,检查连接。
从最小操作开始测试#
使用测试服务器或可控角色,只读取一次并核对角色与游戏。固定操作和分页不是数据库完整导出。保存请求标识以区分新任务与重试。
只记录状态、耗时和非秘密标识,公开报告删除 token 与玩家个人资料。更新密钥、权限或包后重新检查。
不要给所有集成同一个管理员 token。提供组件凭据时使用最小权限并撤销闲置凭据。修改接口或账户权限后重新测试成功与拒绝路径,不能依赖数月前的成功记录。
- 核对自己的服务器成功,以及错误/已撤销凭据被拒绝。
- 无权限人员必须被拒绝,不在其他客户服务器上测试。
- 分别显示 pending、failed、expired、done,不能统一显示成功。
- 资金 unknown_outcome 时先检查实时余额与审计,不得立即重新写入。
区分员工浏览器请求与服务器协议#
/api/tenant_db_bridge.php 通过员工会话认证。需要 POST、application/json、有效 _csrf,以及当前租户账号;请求体上限 4096 字节。action 可以是 enqueue 或 result。发送服务器许可证不会创建浏览器会话。读取权限不等于余额写入权限,每个操作还会检查授权。
/api/server_db_bridge.php 用于游戏服务器发送健康状态、领取任务和返回结果。它使用 POST JSON 和 Bearer 服务器许可证,请求体上限 65536 字节。浏览器 Cookie 或 CSRF 不能替代这个协议。先确认调用路径,不要把另一条路径的凭据当作修复方法,也不要用任意 JSON 模仿内置资源协议。
区分接受请求与完成任务#
ok=true 可能只说明 HTTP 请求被接受,并不能证明游戏操作完成。一起跟踪 request 内的 id、operation 和 status。pending 等待处理,claimed 已被服务器领取;done 已完成,failed 失败,expired 超时。读取结果时保留相同 server_id 和 request_id 上下文。
查看最终状态及 error 后才显示成功。相同待处理参数可能返回现有任务,但不是永久无限重试保证。余额写入出现 unknown_outcome 时停止进一步写入。超时或无效结果不能证明余额没有改变。结合实时余额、原目标及审计记录调查,不要删除记录强行重试。
提供简短且清理过的开发错误记录#
405 检查方法,415 检查 JSON Content-Type,400 检查有效 JSON 与允许字段。浏览器路径的 401 检查会话,419 检查 CSRF,正常重新打开页面。404 核对服务器与请求上下文,不要尝试其他客户的记录。429 等待已有任务。
503 或网络结果不确定时,记录时间、端点、HTTP 状态、操作与非秘密引用。下方示例仅为支持说明,不是 API 请求体。移除 Cookie、Authorization、_csrf、许可证与玩家数据。修复对应认证或格式环节,不要用快速重试掩盖问题;首先以一次受控读取验证。
Endpoint: /api/tenant_db_bridge.php
Method: POST
HTTP status: 419
Error: csrf_failed
Operation: players.list
Reference: YOUR_REQUEST_REFERENCE
Time: YOUR_ERROR_TIME用两个经过核对的 JSON 请求读取一页玩家记录#
下面的例子适用于已经登录自己账户面板的浏览器,用来读取第一页玩家记录。服务器 123 和请求 ID 都是虚构示例;请使用自己的服务器编号,以及 enqueue 响应中的 request.id。把 CURRENT_PAGE_CSRF 替换为当前页面有效的 CSRF 值。它不是服务器许可证,也不应复制到客服消息中。请求需要同源 POST、application/json 和浏览器登录会话。读取要求具备 servers.manage 或 players.view 权限;只读演示模式会拒绝 enqueue。不要把服务器许可证当作浏览器登录凭据。
第一个请求体仅传入空 cursor,该操作每页最多返回 25 条记录。不要添加 limit、SQL、表名、连接字符串或修改金额的参数。如果第一次响应是 pending,请用第二个请求体查询同一个任务,而不是重新 enqueue。在状态为 done 时读取 request.result.items;如果 request.result.has_more 为 true,下次主动翻页时传入 request.result.next_cursor。空列表必须结合成功完成状态解释,不能把尚未完成的查询当成没有玩家。模板中没有可用的秘密凭据。首次测试只在自己的测试服务器执行一次读取,不要借此向公开的浏览器扩展提供管理员访问能力。
POST /api/tenant_db_bridge.php
Content-Type: application/json
Enqueue:
{
"_csrf": "CURRENT_PAGE_CSRF",
"server_id": 123,
"action": "enqueue",
"operation": "players.list",
"params": {"cursor": ""}
}
Result (use request.id from the enqueue response):
{
"_csrf": "CURRENT_PAGE_CSRF",
"server_id": 123,
"action": "result",
"request_id": "00112233445566778899aabbccddeeff"
}区分 HTTP 超时与任务到期时间#
假设 enqueue 在 14:03:10 被接受,并且已经保存 request.id,但后续 result 查询遇到网络中断。面板中的单次 HTTP 请求可能在 12 秒后停止,而排队任务从创建时起 120 秒后到期。浏览器中止请求并不会取消服务器上的任务。因此,“没有收到响应”不能直接标记成任务 expired 或 failed。保留已知 ID,连接恢复后使用同一个 server_id 查询 result。正常面板每三秒查询一次等待中的结果,不需要添加持续高速轮询。记录最后确认的状态,不要用本地计时猜测任务结果。
如果只读 players.list 最终返回 expired 和 request_expired,可记录错误、修复网络后,再主动发起新的读取。对于 player.money.set,任务在 claimed 后到期,或返回无效结果,都可能产生 unknown_outcome;这并不证明余额没有变化。此时停止新的写入,检查实时余额和已有操作记录。结果不是无限期档案,过期记录之后会被有界清理逐步删除。如果记录已经查不到,不要通过再提交一次金额修改来猜测原操作的结果。给客服保留不含秘密的引用、时间、operation 和最后已知状态即可;不要附带 cookie、CSRF 值或许可证。
Illustrative observations; not an API request body:
14:03:10 enqueue accepted; save request.id
14:03:22 HTTP timeout; job outcome is not established
Later result with the same server_id + request_id
Read: expired + request_expired -> investigate before a new read
Write: expired + unknown_outcome -> stop writes and reconcile