- POST /v1/chat/completions public route on CRM (not host pass-through) - Bearer token → sha256 fingerprint → ListByFingerprint → governance check - paused → 403 forbidden, retired/deleted → 403 - ProxyRouteChatCompletions to upstream - NewAPIHandler/NewAPIHandlerWithAuth: optional dsn param for gateway SQLite access - ListByFingerprint in user_keys_repo
2.4 KiB
2.4 KiB
V3-1 网关治理执行计划
目标:在 CRM 新增公开
/v1/chat/completions入口,用户在入口用 portal key 认证,CRM 校验admin_status后再转发到宿主,实现 0 延迟的 pause/resume 治理阻断。
改动概览
| 文件 | 改动 |
|---|---|
internal/app/http_api.go |
新增 POST /v1/chat/completions 公开路由(无 admin auth),调用治理校验 + 转发 |
internal/app/route_proxy_api.go |
新增 user-key 认证和治理校验的入口函数 |
internal/app/openaicompat_handler.go(新文件) |
OpenAI-compatible 请求解析 + user-key auth 提取 |
deploy/tksea-portal/nginx/ 或部署脚本 |
加 location /v1 { proxy_pass http://127.0.0.1:18190; } |
执行分步
Step 1: 新增公开 /v1/chat/completions 路由
在 internal/app/http_api.go 中,在 NewAPIHandlerWithAuth 函数注册路由处(在 admin auth 区块之外)添加:
mux.Handle("POST /v1/chat/completions", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
handlePublicChatCompletions(w, r, actions.UserKeyHandler)
}))
注意必须放在 requireAdminAccess 包的外面,这样用户不需要 admin token。
Step 2: 实现 handlePublicChatCompletions
func handlePublicChatCompletions(w http.ResponseWriter, r *http.Request, ukh *UserKeyHandler) {
// 1. 提取 Bearer token → user_key_id
// 2. 查 user_keys 表,校验 admin_status != "paused"
// 3. 获取 key 的 subject_id 和 logical_group_id
// 4. 调用 buildRouteChatCompletionsAction 或 buildProxyRouteChatCompletionsAction 转发
// - 传入 gateway_api_key = managed key(来自 user_key 的 managed subscription)
// - 传入 subject_id = user_key 的 owner_subject_id
// - 传入 model = 请求体中的 model
// - 传入 messages = 请求体中的 messages
// 5. 返回 OpenAI-compatible chat completion 响应形状
}
Step 3: deploy 脚本更新
更新 nginx 配置,让 location /v1 指向 CRM 的 18190。