mirror of
https://github.com/aiclientproxy/proxycast.git
synced 2026-09-21 12:44:14 +08:00
fix: 修复 /v1/messages 端点返回 Anthropic 标准错误格式
- 新增 verify_api_key_anthropic 函数,返回 Anthropic 标准错误格式
- 更新 /v1/messages、/:selector/v1/messages、/api/provider/:provider/v1/messages 端点使用新认证函数
- 优先检查 x-api-key header(Anthropic 标准)
- 错误响应格式: {"type": "error", "error": {"type": "authentication_error", "message": "..."}}
Fixes #3
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 166 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 169 KiB |
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "proxycast",
|
||||
"private": true,
|
||||
"version": "0.12.0",
|
||||
"version": "0.12.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "proxycast"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
description = "AI API Proxy Desktop App"
|
||||
authors = ["you"]
|
||||
edition = "2021"
|
||||
|
||||
+50
-3
@@ -877,6 +877,50 @@ async fn verify_api_key(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Anthropic 格式的 API key 验证
|
||||
/// 返回 Anthropic 标准错误格式:{"type": "error", "error": {"type": "...", "message": "..."}}
|
||||
async fn verify_api_key_anthropic(
|
||||
headers: &HeaderMap,
|
||||
expected_key: &str,
|
||||
) -> Result<(), (StatusCode, Json<serde_json::Value>)> {
|
||||
let auth = headers
|
||||
.get("x-api-key")
|
||||
.or_else(|| headers.get("authorization"))
|
||||
.and_then(|v| v.to_str().ok());
|
||||
|
||||
let key = match auth {
|
||||
Some(s) if s.starts_with("Bearer ") => &s[7..],
|
||||
Some(s) => s,
|
||||
None => {
|
||||
return Err((
|
||||
StatusCode::UNAUTHORIZED,
|
||||
Json(serde_json::json!({
|
||||
"type": "error",
|
||||
"error": {
|
||||
"type": "authentication_error",
|
||||
"message": "No API key provided. Please set the x-api-key header."
|
||||
}
|
||||
})),
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
if key != expected_key {
|
||||
return Err((
|
||||
StatusCode::UNAUTHORIZED,
|
||||
Json(serde_json::json!({
|
||||
"type": "error",
|
||||
"error": {
|
||||
"type": "authentication_error",
|
||||
"message": "Invalid API key"
|
||||
}
|
||||
})),
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn chat_completions(
|
||||
State(state): State<AppState>,
|
||||
headers: HeaderMap,
|
||||
@@ -1293,7 +1337,8 @@ async fn anthropic_messages(
|
||||
headers: HeaderMap,
|
||||
Json(mut request): Json<AnthropicMessagesRequest>,
|
||||
) -> Response {
|
||||
if let Err(e) = verify_api_key(&headers, &state.api_key).await {
|
||||
// 使用 Anthropic 格式的认证验证(优先检查 x-api-key)
|
||||
if let Err(e) = verify_api_key_anthropic(&headers, &state.api_key).await {
|
||||
state
|
||||
.logs
|
||||
.write()
|
||||
@@ -2276,7 +2321,8 @@ async fn anthropic_messages_with_selector(
|
||||
headers: HeaderMap,
|
||||
Json(request): Json<AnthropicMessagesRequest>,
|
||||
) -> Response {
|
||||
if let Err(e) = verify_api_key(&headers, &state.api_key).await {
|
||||
// 使用 Anthropic 格式的认证验证
|
||||
if let Err(e) = verify_api_key_anthropic(&headers, &state.api_key).await {
|
||||
state.logs.write().await.add(
|
||||
"warn",
|
||||
&format!("Unauthorized request to /{}/v1/messages", selector),
|
||||
@@ -2523,7 +2569,8 @@ async fn amp_messages(
|
||||
headers: HeaderMap,
|
||||
Json(mut request): Json<AnthropicMessagesRequest>,
|
||||
) -> Response {
|
||||
if let Err(e) = verify_api_key(&headers, &state.api_key).await {
|
||||
// 使用 Anthropic 格式的认证验证
|
||||
if let Err(e) = verify_api_key_anthropic(&headers, &state.api_key).await {
|
||||
state.logs.write().await.add(
|
||||
"warn",
|
||||
&format!(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "ProxyCast",
|
||||
"version": "0.12.0",
|
||||
"version": "0.12.1",
|
||||
"identifier": "com.proxycast.app",
|
||||
"build": {
|
||||
"beforeDevCommand": "npm run dev",
|
||||
|
||||
Reference in New Issue
Block a user