资讯动态

Helicone Jawn 服务 Controller 目录结构与认证路由机制详解

发布时间:2026/9/17 15:52:42 来源:尧图企业网站定制
Helicone Jawn 服务 Controller 目录结构与认证路由机制详解【免费下载链接】helicone Open source LLM observability platform. One line of code to monitor, evaluate, and experiment. YC W23 项目地址: https://gitcode.com/GitHub_Trending/he/helicone导读本文以 valhalla/jawn/src/controllers/README.md 为骨架系统梳理 Helicone 观测平台后端服务 Jawn 的 Controller 组织方式、公开/私有路由的认证规则与 Swagger 文档自动生成机制。读完本文你将掌握/v1/public路由为何免认证、其他路由如何校验 API Key 与读写权限、/private与/public两个 Controller 目录在文档生成上的差异以及如何在实际开发中正确新增一个受保护或公开的 API 端点。一、Controllers 目录结构与职责划分Jawn 服务Helicone 的后端 API 服务将所有 HTTP 接口以 TSOA Controller 的形式组织在valhalla/jawn/src/controllers/目录下目录内部分为private/与public/两个子目录它们共同构成了 Jawn 对外 API 的能力全集valhalla/jawn/src/controllers/ ├── README.md # 本文所依据的目录结构说明 ├── private/ # 内部/管理功能不会出现在公开文档中 │ ├── router/ │ │ └── controlPlaneController.ts │ ├── adminController.ts │ ├── adminWalletController.ts │ ├── alertController.ts │ ├── filterController.ts │ ├── logController.ts │ ├── organizationController.ts │ ├── rateLimitController.ts │ ├── settingsController.ts │ └── ... # 其余内部控制器 └── public/ # 面向用户/客户端的 API自动生成完整文档 ├── __tests__/ │ ├── heliconeSqlController.test.ts │ └── requestController.test.ts ├── agentController.ts ├── apiKeyController.ts ├── creditsController.ts ├── customerController.ts ├── evalController.ts ├── metricsController.ts ├── modelController.ts ├── modelRegistryController.ts ├── piController.ts ├── promptController.ts ├── requestController.ts ├── sessionController.ts ├── userController.ts ├── vaultController.ts ├── webhookController.ts └── ... # 其余公开控制器需要特别强调的是原 README 开篇即指出private与public这两个文件夹仅代表哪些控制器会被自动生成文档它们并不决定路由是否需要认证。是否免认证只由路由路径本身决定——凡是路径以/v1/public开头的路由都会跳过认证无论它位于哪个目录。这是一个容易混淆、但极其关键的约定。二、认证与路由规则真正的裁判是中间件原 README 明确指出认证规则的权威实现在middleware/auth.ts。在 valhalla/jawn/src/middleware/auth.ts 中authMiddleware按以下顺序决策2.1 白名单前缀/v1/public直接放行代码中使用显式白名单数组来防止意外暴露源码注释原话// valhalla/jawn/src/middleware/auth.ts const PUBLIC_ROUTE_PREFIXES [ /v1/public/model-registry, // 模型注册表公开查询模型与定价 /v1/public/stats, // 公开统计 /v1/public/security, // 安全公告 /v1/public/alert-banner, // 公告横幅 /v1/public/status/provider, // 供应商状态 /v1/public/pi, // 公共 Pi产品信息接口 /v1/public/compare, // 模型对比 /v1/public/waitlist, // 等候名单 ]; if (PUBLIC_ROUTE_PREFIXES.some((prefix) req.path.startsWith(prefix))) { next(); // 直接进入下一个中间件不校验 API Key return; }注意这里使用的是startsWith前缀匹配而非精确匹配因此/v1/public/model-registry/models、/v1/public/pi下的所有子路径同样享受免认证。也就是说原 README 中Routes starting with/v1/public- Bypass authentication entirely (no API key required)的描述在源码层面落地为一份显式维护的前缀白名单任何新公开路由都必须显式登记在此数组中才会生效。2.2 额外的两个 GET 特例除前缀白名单外还有两个按路径 方法双重匹配的公开特例if (req.path /v1/models req.method GET) { next(); return; } if (req.path /v1/organization req.method GET) { next(); return; }即GET /v1/models模型列表与GET /v1/organization组织信息查询也允许匿名访问而同一路径下的写操作如 POST/PATCH仍必须认证。2.3 默认兜底所有其他路由必须认证对于不在白名单内的请求中间件通过RequestWrapper读取请求头中的认证信息交由getHeliconeAuthClient().authenticate(...)完成鉴权见 authFromRequest随后执行三项检查认证是否失败authParams.error是否缺少组织 IDauthParams.data?.organizationIdAPI Key 权限是否覆盖所需权限——写方法POST/PUT/PATCH/DELETE要求w权限读方法要求r权限const isWriteMethod [POST, PUT, PATCH, DELETE].includes(req.method); const requiredPermission isWriteMethod ? w : r; // /v1/log/request 端点特例记录日志使用写权限 w const isLogEndpoint req.path /v1/log/request;任一检查不通过即返回401{ error, trace: isAuthenticated.error }。关键事实认证失败返回 401而中间件外层catch到异常时返回 400Invalid token.。2.4 管理员路由/v1/admin的双重校验中间件还对/v1/admin前缀做了额外约束/v1/admin/has-feature-flag除外要求认证凭证类型必须为 JWTauthorization.data?._type ! jwt时直接 401随后调用 authCheckThrow 查询 Postgres 中admins表确认该用户 ID 确实被登记为管理员否则抛出Unauthorized。这正对应原 README 中v1/admin- Requires authentication admin privileges的描述。2.5 与 TSOA 装饰器的关系Security(api_key)是纸面声明原 README 中有一句容易引起困惑的话TheSecurity(api_key)was never implemented properly。其含义在源码中可以完整印证authentication.ts 中TSOA 生成代码所需的expressAuthentication直接return null注释明确写道This file is only used for tsoa generated code. We use express middleware for authentication, because we can have more control and flexibility——即 TSOA 层面的安全钩子被有意留空真正的认证由 index.ts 中的v1APIRouter.use(authMiddleware)这一 Express 中间件统一完成因此Controller 类上的Security(api_key)装饰器只服务于 Swagger 文档的展示在 UI 上标记该端点需要 Bearer Token并不产生任何实际校验逻辑。也就是说Controller 编写者不应依赖装饰器保证安全而应确保路由路径与authMiddleware的白名单/默认规则相符。三、路由挂载与文档生成机制3.1 双 Router 注册流程在 valhalla/jawn/src/index.ts 中应用搭建了未认证路由器 v1 API 路由器两级结构const unAuthenticatedRouter express.Router(); // 挂载 /docs 与 /download/swagger.json const v1APIRouter express.Router(); // 所有 v1 API v1APIRouter.use(/v1/public/stats, unauthorizedCacheMiddleware(stats, 4 * 60 * 60 * 1000)); v1APIRouter.use(authMiddleware); // 统一认证入口 if (IS_RATE_LIMIT_ENABLED) { v1APIRouter.use(limiter); } registerPublicTSOARoutes(v1APIRouter); // 注入 public 控制器生成的路由 registerPrivateTSOARoutes(v1APIRouter); // 注入 private 控制器生成的路由从源码结构可以看出请求依次经历CORS → body 解析 →unauthorizedCacheMiddleware仅/v1/public/stats缓存 4 小时→authMiddleware认证 → 可选限流limiter→ TSOA 生成路由分发。而/docsSwagger UI与/download/swagger.json挂在未认证路由器上意味着公开文档页面本身无需认证即可访问。3.2 两套 TSOA 配置驱动文档生成private 不生成文档、public 生成完整文档的约定由两套独立的 TSOA 配置实现配置扫描目录输出目录tsoa-public.jsonsrc/controllers/public/**/*Controller.tssrc/tsoa-build/public含 swagger.jsontsoa-private.jsonsrc/controllers/private/**/*Controller.tssrc/tsoa-build/private仅路由不对外暴露文档两份配置都声明了 OpenAPI 3 规范specVersion: 3与统一的api_key安全定义Authorization头格式Bearer YOUR_API_KEY并声明服务器地址https://api.helicone.ai/与本地开发地址http://localhost:8585/。运行时 index.ts 只把public的 swagger.json 交给 Swagger UI 展示private 的构建产物仅用于注册路由——这正是原 README 所说/privateWill not be in the public docs的落地方式。3.3 文档从何而来装饰器即文档公开文档的内容全部来自 Controller 源码中的 TSOA 装饰器与 JSDoc 注释。以 modelRegistryController.ts 为例Route(/v1/public/model-registry) Tags(Model Registry) export class ModelRegistryController extends Controller { /** * Get all available models from the registry * summary Returns a comprehensive list of all AI models with their configurations, pricing, and capabilities * description This endpoint provides detailed information about all available models including: * - Model metadata (name, author, context length, training date) * - Supported providers and endpoints * - Pricing information (per million tokens ...) * - Input/output modalities (text, image, audio, video) * - Supported parameters (temperature, max_tokens, etc.) * - Available capabilities (audio, video, image, thinking, web_search, caching) * No authentication required - this is a public endpoint. */ Get(/models) ExampleModelRegistryResponse({ ... }) public async getModelRegistry(): PromiseResultModelRegistryResponse, string { ... } }Route决定最终 URL 前缀Tags决定 Swagger 分组Summary/Description生成端点说明Example为响应体提供示例。开发时只需修改这些注解重新运行 TSOA 构建即可刷新/docs页面。四、路由示例对照认证与否只看路径原 README 给出的三类示例在源码中均有对应实现整理为下表以便对照Controller目录路由注解是否认证权限层级源码依据ModelRegistryControllerpublic/Route(/v1/public/model-registry)免认证白名单前缀命中公开只读modelRegistryController.tsExperimentController等业务控制器public/Route(v1/experiment)等需要 API Keyr/w读写权限piController.ts 等AdminControllerprivate/Route(v1/admin)需要 JWT 管理员身份admins表校验adminController.tsWaitListControllerprivate/Route(v1/waitlist)需要 API Key目录为 private 但并非免认证r/wwaitlistController.tsOrganizationControllerprivate/Route(v1/organization)GET 免认证其余需认证特殊特例organizationController.ts值得注意的反直觉点waitlistController.ts位于private/目录不生成公开文档但它的路由v1/waitlist仍需 API Key 认证而modelRegistryController.ts位于public/目录且免认证。这再次印证了原 README 的核心结论——决定认证与否的是路由路径而不是 Controller 所在的目录。五、开发实践如何新增一个 Controller/端点综合以上机制在 Jawn 中新增端点的正确步骤是选择目录面向用户与 SDK 的能力放入src/controllers/public/会被自动生成文档内部管理/运维能力放入src/controllers/private/不出现在公开文档编写 Controller使用 TSOA 装饰器声明Route、Tags、方法装饰器Get/Post/…与 JSDoc 注释方法内返回ResultT, string来自packages/common/result确定认证形态需认证 → 路由前缀保持非/v1/public默认即受保护并在Security(api_key)声明文档标记免认证 → 路由前缀必须以/v1/public/开头同时将前缀登记进 authMiddleware 的 PUBLIC_ROUTE_PREFIXES 白名单二者缺一不可管理员专属 → 使用/v1/admin前缀会自动叠加 JWT 与admins表校验重新构建 TSOA运行 TSOA 构建命令使src/tsoa-build/public或private中的 routes 与 swagger.json 重新生成验证本地启动服务后访问/docs查看公开端点文档为关键 public 控制器补充单元测试参考 requestController.test.ts 与 heliconeSqlController.test.ts 的组织方式。六、安全设计要点小结从认证机制的源码实现可以提炼出 Jawn 的几条安全设计原则默认安全secure by default除显式白名单外所有路由一律要求认证避免新增 Controller 时因疏漏而暴露数据白名单集中管理公开路由必须集中登记在PUBLIC_ROUTE_PREFIXES源码注释明确这是to prevent accidental exposure防止意外暴露杜绝散落在各 Controller 中的隐性公开路由认证与文档解耦Security(api_key)仅是文档声明实际安全完全依赖 Express 中间件因此评审代码时应以中间件白名单为唯一安全依据读写权限分离API Key 具备r/w两种权限写方法强制要求w权限/v1/log/request作为日志写入端点有独立豁免逻辑管理员双层校验/v1/admin既要求 JWT 凭证又需命中admins数据表防止仅凭有效 Key 触达管理能力。结语Helicone Jawn 服务的 Controller 体系以目录管文档、路径管认证为设计核心private/与public/只决定 OpenAPI 文档是否对外生成而真正的访问控制统一收敛在 middleware/auth.ts 的白名单与默认认证规则之中。理解这套约定既是安全审查新端点的前提也是向 Jawn 贡献新 API 时的第一道门槛。【免费下载链接】helicone Open source LLM observability platform. One line of code to monitor, evaluate, and experiment. YC W23 项目地址: https://gitcode.com/GitHub_Trending/he/helicone创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价