fix: 修复 Claude 代理对智谱 AI 的认证兼容
All checks were successful
Docker Build and Push / build-and-push (push) Successful in 3m15s

- 将 x-api-key 头自动转换为 Authorization: Bearer 格式
- 检测上游是否为智谱 AI,自动适配认证方式
- 保持标准 Claude API 认证头的直接透传

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
D8D Developer
2026-03-20 15:21:48 +00:00
parent fdfc95ef6f
commit c5e63feaa3

View File

@@ -16,15 +16,42 @@ function getBaseUrl(): string {
return process.env.ANTHROPIC_BASE_URL || 'https://api.anthropic.com';
}
// 提取需要透传的 headers
// 提取需要透传的 headers,并处理认证头转换
function extractProxyHeaders(req: Request): Record<string, string> {
const headers: Record<string, string> = {};
for (const header of PROXY_HEADERS) {
const value = req.headers[header];
if (value) {
headers[header] = Array.isArray(value) ? value[0] : value;
const baseUrl = getBaseUrl();
// 如果上游是智谱 AI 等,需要将 x-api-key 转换为 Authorization: Bearer
if (baseUrl.includes('bigmodel.cn') || baseUrl.includes('open.bigmodel')) {
// 优先使用 x-api-key其次使用 Authorization
const rawHeaders = req.headers as Record<string, string | string[] | undefined>;
const xApiKey = rawHeaders['x-api-key'];
const authHeader = rawHeaders['authorization'];
const apiKey = (Array.isArray(xApiKey) ? xApiKey[0] : xApiKey) ||
(Array.isArray(authHeader) ? authHeader[0] : authHeader)?.replace?.(/^Bearer\s+/i, '');
if (apiKey) {
headers['authorization'] = `Bearer ${apiKey}`;
}
// 复制其他 headers
for (const header of PROXY_HEADERS) {
if (header === 'x-api-key' || header === 'authorization') continue;
const value = req.headers[header];
if (value) {
headers[header] = Array.isArray(value) ? value[0] : value;
}
}
} else {
// 标准 Claude API直接透传
for (const header of PROXY_HEADERS) {
const value = req.headers[header];
if (value) {
headers[header] = Array.isArray(value) ? value[0] : value;
}
}
}
return headers;
}