)
Weave Router 反馈链接设计无登录反馈页 HMAC 签名 token 如何保证安全完整指南【免费下载链接】routerModel router for agentic systems. Routes every prompt to the right model in 50ms. Cut costs 40-70% with just an endpoint change.项目地址: https://gitcode.com/GitHub_Trending/router101/routerWeave Router 是一个面向智能体系统的模型路由器Model Router能在 50ms 内把每个提示词路由到最合适的模型仅通过更换一个端点即可降低 40%~70% 的成本。它的响应末尾会附带一条无登录反馈链接no-login feedback link用户无需注册或登录就能对路由决策点赞/点踩。那么这条公开链接凭什么安全答案是一枚 HMAC-SHA256 签名 token——签名密钥只留在服务端链接本身即唯一凭证。为什么反馈链接不需要用户登录传统做法是让反馈页挂登录态但终端里的 Claude Code、Codex 用户根本没有登录 Weave 后台的场景要求登录后才能点一下反馈率会直接崩盘。Weave Router 的思路相反链接即凭证URL 里的那串 token 就是唯一的身份凭证公开路由不挂任何鉴权中间件一次一链token 在路由完成的那一刻为这一个请求单独签发不可猜测、不可复用泄露无爆炸半径最坏情况也就是别人能给你这一条请求评个分碰不到其他请求、更碰不到其他安装这套设计落在 internal/feedback/token.go 中代码注释写得很直白纯函数HMAC base64无 I/OWeave 后端永远看不到密钥。一枚签名 token 里装了什么签发逻辑在 internal/feedback/token.go 的Signer.Mint中。token 结构只有一段base64url(JSON载荷) . base64url(HMAC-SHA256签名)载荷Claims结构体包含 5 个字段字段含义iid安装 ID定位路由上下文eid外部 ID把反馈归属到 Weave 组织rid请求 ID反馈针对哪一次路由uid可选路由器用户 ID归属到具体用户expUnix 过期时间戳0 表示永不过期关键点载荷是明文、签名是密文。服务端不存任何会话表验证时只需用自己的密钥对同样的载荷重新算一遍 HMAC 并比对——这就是无状态的含义任何一台持有密钥的实例都能验证任何 token天然横向扩展。三个公开端点路由决策的反馈闭环服务端的挂载点在 internal/server/server.go只有配置了ROUTER_FEEDBACK_LINK_SECRET后才会挂载/v1/feedback分组。处理逻辑集中在 internal/api/feedback/feedback.go端点作用GET /v1/feedback/link/:token打开无登录反馈页返回该请求的路由上下文选了哪个模型/供应商和已有评价POST /v1/feedback/link提交评分 可选文字评论请求体上限 64KB评分只能是 up/downGET /v1/feedback/rate?ttokenrup|down终端响应尾部内嵌的一键点赞/点踩链接直接返回一个小小的确认页其中x-router-feedback-url响应头由 internal/proxy/feedback.go 中的setFeedbackLinkHeader写入——即每次推理响应发出前路由器顺手把base/f/token塞进响应头GUI 客户端据此渲染反馈入口。状态码的讲究404 vs 410一个容易忽略但很体现功力的细节token 校验失败会映射成两种不同的 HTTP 状态码见writeTokenError404 Not Found—— token 格式错误或签名不符链接根本不存在410 Gone—— 签名有效但已过期链接曾经存在但现在作废这样前端页面和用户能区分你拿到的是坏链接和链接过期了而不是笼统地报 500。HMAC-SHA256 验证链路安全细节在哪里验证函数Verifyinternal/feedback/token.go按四步走每一步都在堵一种攻击面切分与格式检查—— 按第一个.切出载荷和签名缺任一半直接判无效恒定时间比较—— 用crypto/subtle.ConstantTimeCompare比对签名防止攻击者通过响应耗时差异逐字节猜出签名时序侧信道解码并反序列化载荷—— base64 解码失败或 JSON 解析失败一律判无效过期判断—— 签名通过但exp已到时返回专门的已过期错误对应 410签发端同样有防御性设计Mint在序列化这类固定结构时理论上不会失败但代码仍选择降级为不输出链接而不是在请求路径上 panic未配置密钥时NewSigner返回 nilMint返回空串——对调用方来说功能未启用和token 无效不可区分不泄露部署配置。配置开关两个环境变量决定功能是否启用组合根在 cmd/router/main.go 中接线ROUTER_FEEDBACK_LINK_SECRET—— HMAC 签名密钥。不设置则整个功能关闭响应不带反馈链接头ROUTER_FEEDBACK_BASE_URL—— 反馈页的公开基础 URL只设密钥没设它端点会挂载但不会对外暴露链接token TTL 也可配置非正数 TTL 表示永不过期这种缺配置即降级的模式让自托管用户零负担不需要反馈功能就什么都不用做。数据落地反馈存到哪里、如何回流提交路径在 internal/proxy/feedback.go 的SubmitFeedback先写数据库权威数据源upsert 进路由器自己的反馈表表结构见迁移文件 db/migrations/0020_router-feedback.up.sql再发遥测 span尽力而为向 Weave 后端发一个router.feedbackOTLP span由后端镜像到其自身的反馈表span 队列满了就丢弃不影响用户提交也就是说数据库写入是权威遥测只是同步通道——顺序反过来的话监控系统抖动就会丢真实反馈。彩蛋终端里的 /rf 快捷指令对 Claude Code、Codex 这类终端客户端链接头之外还有一层更土味但更顺手的交互流式响应结束后会追加一行尾部提示教用户输入/rf 好体验或/rf -差体验可附注如/rf - too slow。相关命令说明见 install/commands/rf.md。两个耐人寻味的设计决策尾提示刻意不带链接Claude Code 的 markdown 渲染会把label打印成label (url)内嵌签名链接等于把整串 token 抖在屏幕上反而泄露凭证只在真聊天回合出现IDE 内联编辑、diff 应用、commit message 等表面会被排除子代理派发、压缩、标题生成等机器回合也不会追加——尾提示只会出现在用户直接发起的主循环/工具结果回合安全设计小结机制防住的攻击每次请求独立签发 token一个链接不能评价/篡改其他请求HMAC-SHA256 签名 恒定时间比较伪造签名、时序侧信道逐字节爆破TTL 过期 404/410 语义分离链接长期滞留、钓鱼复用请求体 64KB 上限、评分白名单up/down恶意客户端刷超大请求体密钥不出服务端、载荷无敏感信息即使链接外泄也无从推导密钥或他人身份缺配置即静默关闭误开公开端点的运维风险一句话总结Weave Router 用一次性、可自验证、带过期的签名 token 替代了登录态让一个零门槛的反馈按钮在不牺牲任何安全性的前提下嵌进了每一次模型路由的闭环里。想深入源码从 internal/feedback/token.go签发与验证和 internal/api/feedback/feedback.goHTTP 层这两个文件读起即可。【免费下载链接】routerModel router for agentic systems. Routes every prompt to the right model in 50ms. Cut costs 40-70% with just an endpoint change.项目地址: https://gitcode.com/GitHub_Trending/router101/router创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考