管理端 API:鉴权、错误处理与响应包装
如果你把 /send 当作“数据面”(让外部系统把消息送进来),那管理端 API 就是“控制面”:
- 创建/维护 Channel(微信/企业微信凭证)
- 创建 App(生成 appKey、选择推送策略)
- 管理绑定关系(OpenID)
- 查看历史与排障(Messages/Stats)
控制面最怕两件事:
- 被扫到:任何一个不该公开的接口暴露出去,风险都比
/send高得多。 - 不可观测:一旦线上出问题,UI 只给你一句“失败”,你会非常痛苦。
所以这篇的核心不是“有哪些路由”,而是:为什么控制面要强鉴权、要统一错误语义。
路由分层(不是为了好看,而是为了边界清楚)
Node Functions 的路由模块集中在:
node-functions/routes/*
按责任划分基本是:
auth.ts:登录/令牌相关config.ts:系统配置(包含管理员令牌重置等)channels.ts:渠道管理apps.ts:应用管理openids.ts:绑定用户messages.ts:消息历史stats.ts:统计信息
这类划分的价值在于:当你要扩一个“新的推送平台”或“新的领域对象”,你知道它应该落在什么位置。
强鉴权:管理员令牌
管理端 API 是控制面,因此默认策略应该是:
- 默认拒绝(没有 token 就不能访问)
- 尽量少的攻击面(路由不要暴露多余信息)
中间件导出在:
node-functions/middleware/index.ts(adminAuth、hasValidAdminToken)
你可以把它理解成一条“门禁线”:
flowchart LR
UI[管理后台 UI] -->|携带 Admin Token| API[管理端 API]
API -->"|"adminAuth"| SVC[业务服务层]
SVC --> KV["KV/外部 API"]
关键取舍:
/send可以弱认证(appKey),因为它是数据面。- 管理端必须强鉴权,因为它能“创建 appKey / 读取历史 / 修改渠道凭证”。
统一错误处理:把“线上玄学”变成“稳定语义”
在 serverless/边缘环境里,错误来源非常多:
- 参数错误
- KV 访问失败(baseUrl/internal key/namespace)
- 微信 API 失败(token 过期、权限不足、用户未关注)
如果你不统一错误语义,你会得到一个很糟糕的系统:
- 前端无法区分“需要用户修复”还是“系统自己会恢复”
- 日志里一堆 stack trace,但 UI 只显示“请求失败”
所以需要:
error-handler:把异常收敛成可控输出response-wrapper:让每个 API 返回同一种结构ErrorCodes/ApiError:让错误能被分类
统一响应结构通常类似:
code:错误码(0 表示成功)message:可读消息data:返回数据
真正的收益不是“看起来规范”,而是:
- 前端只要写一套拦截器/提示策略
- 新增接口不会变成“每个接口都要特殊处理”
常见坑(你会真实遇到)
-
一切接口都 401/403:
- 大概率是 token 没带/带错
- 其次是 token 重置后前端还在用旧 token
-
某些接口偶发 500:
- 不要急着怀疑业务逻辑,先看 KV 访问是否稳定(
KV_BASE_URL、内部 key)
- 不要急着怀疑业务逻辑,先看 KV 访问是否稳定(
-
UI 显示“渠道不可用”:
- 这通常不是 UI bug,而是 token status 真的在报错(凭证/权限/网络)
启发:控制面系统要“严”和“稳”
- 严:默认拒绝、最小暴露面。
- 稳:错误语义稳定、可观测信息充分(否则线上排障会很折磨)。
