From 4bb2050093e64bbdd705bd879bc9c5d0bbd898ff Mon Sep 17 00:00:00 2001 From: shaw Date: Sat, 19 Jul 2025 21:13:11 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DAPI=20Key=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E9=99=90=E5=88=B6=E5=8A=9F=E8=83=BD=E4=B8=8D=E7=94=9F?= =?UTF-8?q?=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在apiKeyService.validateApiKey()中添加缺失的enableModelRestriction和restrictedModels字段返回 - 添加详细的调试日志来追踪模型限制检查的执行流程 - 解析存储在Redis中的restrictedModels JSON数据 - 确保模型限制数据正确传递到claudeRelayService 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- src/services/apiKeyService.js | 12 +++++++++++- src/services/claudeRelayService.js | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/services/apiKeyService.js b/src/services/apiKeyService.js index 6b80eaff..d696a623 100644 --- a/src/services/apiKeyService.js +++ b/src/services/apiKeyService.js @@ -108,6 +108,14 @@ class ApiKeyService { logger.api(`🔓 API key validated successfully: ${keyData.id}`); + // 解析限制模型数据 + let restrictedModels = []; + try { + restrictedModels = keyData.restrictedModels ? JSON.parse(keyData.restrictedModels) : []; + } catch (e) { + restrictedModels = []; + } + return { valid: true, keyData: { @@ -115,7 +123,9 @@ class ApiKeyService { name: keyData.name, claudeAccountId: keyData.claudeAccountId, tokenLimit: parseInt(keyData.tokenLimit), - concurrencyLimit: parseInt(keyData.concurrencyLimit || 0), + concurrencyLimit: parseInt(keyData.concurrencyLimit || 0), + enableModelRestriction: keyData.enableModelRestriction === 'true', + restrictedModels: restrictedModels, usage } }; diff --git a/src/services/claudeRelayService.js b/src/services/claudeRelayService.js index f9091757..67179f2b 100644 --- a/src/services/claudeRelayService.js +++ b/src/services/claudeRelayService.js @@ -22,9 +22,19 @@ class ClaudeRelayService { let upstreamRequest = null; try { + // 调试日志:查看API Key数据 + logger.info(`🔍 API Key data received:`, { + apiKeyName: apiKeyData.name, + enableModelRestriction: apiKeyData.enableModelRestriction, + restrictedModels: apiKeyData.restrictedModels, + requestedModel: requestBody.model + }); + // 检查模型限制 if (apiKeyData.enableModelRestriction && apiKeyData.restrictedModels && apiKeyData.restrictedModels.length > 0) { const requestedModel = requestBody.model; + logger.info(`🔒 Model restriction check - Requested model: ${requestedModel}, Restricted models: ${JSON.stringify(apiKeyData.restrictedModels)}`); + if (requestedModel && apiKeyData.restrictedModels.includes(requestedModel)) { logger.warn(`🚫 Model restriction violation for key ${apiKeyData.name}: Attempted to use restricted model ${requestedModel}`); return { @@ -437,9 +447,19 @@ class ClaudeRelayService { // 🌊 处理流式响应(带usage数据捕获) async relayStreamRequestWithUsageCapture(requestBody, apiKeyData, responseStream, clientHeaders, usageCallback) { try { + // 调试日志:查看API Key数据(流式请求) + logger.info(`🔍 [Stream] API Key data received:`, { + apiKeyName: apiKeyData.name, + enableModelRestriction: apiKeyData.enableModelRestriction, + restrictedModels: apiKeyData.restrictedModels, + requestedModel: requestBody.model + }); + // 检查模型限制 if (apiKeyData.enableModelRestriction && apiKeyData.restrictedModels && apiKeyData.restrictedModels.length > 0) { const requestedModel = requestBody.model; + logger.info(`🔒 [Stream] Model restriction check - Requested model: ${requestedModel}, Restricted models: ${JSON.stringify(apiKeyData.restrictedModels)}`); + if (requestedModel && apiKeyData.restrictedModels.includes(requestedModel)) { logger.warn(`🚫 Model restriction violation for key ${apiKeyData.name}: Attempted to use restricted model ${requestedModel}`);