const swagger = require("../../_docs/swagger.json"); const auth = require("../service/biz_auth_verify"); const proxy = require("../service/biz_proxy_service"); /** * 从请求中提取 Token * 支持 Authorization: Bearer xxx 和 query ?token=xxx */ function extractToken(ctx) { const authHeader = ctx.get("Authorization") || ""; if (authHeader.startsWith("Bearer ")) { return authHeader.slice(7).trim(); } return ctx.query.token || ""; } /** * 提取 swagger tags 第一项作为 feature 名(用于套餐功能点校验) */ function pickFeature(spec) { if (spec.tags && spec.tags.length > 0) { return spec.tags[0]; } return null; } /** * 构建转发路由表(供 framework.addRoutes 注册) */ function buildProxyRoutes() { const routes = {}; for (const [path, methods] of Object.entries(swagger.paths)) { for (const [method, spec] of Object.entries(methods)) { const routeKey = `${method.toUpperCase()} ${path}`; routes[routeKey] = async (ctx) => { // 1. 提取 Token const token = extractToken(ctx); if (!token) { ctx.fail("缺少 Token"); return; } // 2. 鉴权:Token + 用户 + 订阅 + 套餐功能点 + 接口权限 + 调用量 const feature = pickFeature(spec); const authResult = await auth.verifyRequest({ token, feature, api_path: path }); if (!authResult.ok) { ctx.fail(authResult.message || "鉴权失败"); return; } // 3. 组装 query(去掉 token 参数,避免泄露) const query = { ...ctx.query }; delete query.token; // 4. 转发到上游 const result = await proxy.forwardRequest({ api_path: path, method: method.toUpperCase(), query, body: ctx.getBody(), headers: ctx.headers || {}, auth_ctx: authResult.context, }); // 5. 根据上游 Success 字段决定响应方式 const upstream = result.data; if (upstream && upstream.Success === true) { ctx.success(upstream); } else { ctx.fail(upstream && upstream.Text ? upstream.Text : "上游请求失败", upstream); } }; } } return routes; } module.exports = { buildProxyRoutes };