fix(glmt): add bearer prefix for openai-compatible endpoints

OpenAI-compatible endpoints like /chat/completions require Authorization header
with 'Bearer ' prefix. Previously the token was sent without prefix, causing
401 Unauthorized errors.

Auto-detects endpoint type based on URL path and formats header accordingly.

Fixes #61
This commit is contained in:
kaitranntt
2025-12-07 22:52:31 -05:00
parent 55197ee42e
commit 077a406df6
+28 -2
View File
@@ -353,6 +353,10 @@ export class GlmtProxy {
const url = new URL(this.upstreamUrl);
const requestBody = JSON.stringify(openaiRequest);
// OpenAI-compatible endpoints require "Bearer " prefix
const token = process.env.ANTHROPIC_AUTH_TOKEN || '';
const authHeader = this.formatAuthHeader(token, url.pathname);
const options: https.RequestOptions = {
hostname: url.hostname,
port: url.port || 443,
@@ -361,7 +365,7 @@ export class GlmtProxy {
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(requestBody),
Authorization: process.env.ANTHROPIC_AUTH_TOKEN || '',
Authorization: authHeader,
'User-Agent': 'CCS-GLMT-Proxy/1.0',
},
};
@@ -425,6 +429,10 @@ export class GlmtProxy {
const url = new URL(this.upstreamUrl);
const requestBody = JSON.stringify(openaiRequest);
// OpenAI-compatible endpoints require "Bearer " prefix
const token = process.env.ANTHROPIC_AUTH_TOKEN || '';
const authHeader = this.formatAuthHeader(token, url.pathname);
const options: https.RequestOptions = {
hostname: url.hostname,
port: url.port || 443,
@@ -433,7 +441,7 @@ export class GlmtProxy {
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(requestBody),
Authorization: process.env.ANTHROPIC_AUTH_TOKEN || '',
Authorization: authHeader,
'User-Agent': 'CCS-GLMT-Proxy/1.0',
Accept: 'text/event-stream',
},
@@ -540,6 +548,24 @@ export class GlmtProxy {
}
}
/**
* Format Authorization header based on endpoint type
* OpenAI-compatible endpoints (chat/completions) require "Bearer " prefix
* Anthropic-compatible endpoints use token directly
*/
private formatAuthHeader(token: string, pathname: string): string {
// OpenAI-compatible endpoints use Bearer token format
const isOpenAICompatible =
pathname.includes('chat/completions') ||
pathname.includes('/v1/') ||
pathname.includes('/paas/');
if (isOpenAICompatible && token && !token.startsWith('Bearer ')) {
return `Bearer ${token}`;
}
return token;
}
/**
* Parse upstream error and return user-friendly error info
*/