在构建 AI 中转服务(如基于 New-API 或 One-API)时,通常会使用 Nginx 作为反向代理来提供 HTTPS 支持和域名解析。然而,在部署完成后进行客户端测试时,常会遇到 POST /v1/chat/completions 请求直接返回 401 Unauthorized 错误的情况。本文将针对该现象进行深度排查、定位,并提供彻底的解决方案。
1. 问题背景与现象
1.1 环境栈
- 前端/客户端:NextChat / LobeChat 或其他标准 OpenAI 格式客户端
- 反向代理层:Nginx
- 后端服务:New-API (运行于本地
127.0.0.1:3000)
1.2 故障现象
客户端在发送对话请求时失败,提示鉴权失败。查阅 Nginx 的 access.log,可以看到如下明确的错误日志:
0.0.0.0 - - [20/Jul/2026:17:49:10 +0800] "POST /v1/chat/completions HTTP/1.1" 401 126 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "-"
现象特征分析:
- 状态码为
401,代表未通过身份验证。 - 返回体大小为
126字节,这符合 New-API 标准的 JSON 报错回包长度(如{"error":{"message":"Invalid external token...","type":"new_api_error"}}),说明请求已经到达了后端,但后端认为没有携带有效的 Token。
2. 原因分析与故障定位
引发该问题的核心原因可以划分为以下三个方向:
2.1 原因一:Nginx 默认丢弃带下划线的非标准请求头
New-API 服务在处理特定客户端流式传输或联动请求时,有时会包含带有下划线 _ 的自定义 HTTP 头部(例如 Authorization_ 或客户端用于传递渠道的自定义 Header)。
- Nginx 默认行为:出于安全考虑,Nginx 默认将
underscores_in_headers设置为off,会自动过滤并丢弃所有请求头名称中包含下划线的 Header。当后端服务拿不到必要的 Header时,就会触发 401。
2.2 原因二:Authorization 头部在代理过程中丢失或被覆盖
在一些复杂的 Nginx 环境中(例如特定的默认模板、集成了外部安全模块或上层全局配置),客户端传入的 Authorization: Bearer sk-... 头部在进入 location / 匹配块时,未被正确继承或透传给 upstream,导致后端收到的 HTTP 请求中 Authorization 字段为空。
2.3 原因三:客户端混淆了管理密码与 API Key
在 New-API 系统中存在两种凭证:
- 系统管理员密码:用于登录 Web 管理控制台。
- **令牌 (Token)**:在控制台“令牌”页面生成的、以
sk-开头的密钥。
如果用户在客户端中错误地将“管理密码”填入 API Key 栏,后端接口层通过/v1/chat/completions校验时会直接拒绝,返回 401。
3. 深度排查步骤
为了快速缩小故障范围,必须通过边界隔离法确定是 Nginx 代理层的问题,还是后端服务本身的问题。
步骤一:绕过代理进行本地环回测试
在 Nginx 所在的服务器本地,使用 curl 直接向后端服务的 3000 端口发起接口请求,以此判定后端状态。执行以下标准命令:
curl http://127.0.0.1:3000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-your_actual_token_here" \
-d '{
"model": "gpt-3.5-turbo",
"messages": [{"role": "user", "content": "say hi"}]
}'
定位结论分流:
- **若本地直接请求成功(返回 200 或模型真实的额度报错)**:
- 诊断结果:后端服务正常,Token 有效。故障根源绝对在 Nginx 代理层(请求头被拦截或剥离)。
- 若本地直接请求依然返回 401:
- 诊断结果:Nginx 配置无误。故障根源在 后端校验。应立即去 New-API 检查该令牌是否被禁用、过期、额度耗尽,或确认是否误填了管理密码。
4. 解决方案
确定为 Nginx 层面的问题后,通过调整 Nginx 配置文件进行修复。
4.1 开启下划线请求头支持
在 server 块内(与 listen 同级)显式声明允许下划线 Header:
server {
listen 443 ssl;
server_name example.com;
# 核心修复项:允许请求头中包含下划线
underscores_in_headers on;
# 后续其他配置...
}
4.2 显式透传验证请求头与清理冲突配置
- 在
location /块内部,明确补充proxy_set_header Authorization映射,确保 Token 强行透传。 - 清理掉写在
location块外部的“悬空”proxy_set_header语句,避免作用域继承混乱。
优化后的完整 server 块配置示例如下:
server {
listen 443 ssl ;
server_name example.com;
# 允许包含下划线的请求头进入
underscores_in_headers on;
index index.php index.html index.htm default.php default.htm default.html;
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log;
# 安全过滤块
location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md) {
return 404;
}
location ^~ /.well-known/acme-challenge {
allow all;
root /usr/share/nginx/html;
}
if ( $uri ~ "^/\.well-known/.*\.(php|jsp|py|js|css|lua|ts|go|zip|tar\.gz|rar|7z|sql|bak)$" ) {
return 403;
}
# 核心反向代理路由
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
# 显式传递客户端真实的验证信息,防止被覆盖或漏传
proxy_set_header Authorization $http_authorization;
# WebSocket 支持
proxy_set_header Connection upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_http_version 1.1;
proxy_ssl_server_name off;
proxy_ssl_name $proxy_host;
proxy_pass http://127.0.0.1:3000;
}
# SSL 协议及安全策略
http2 on;
if ($scheme = http) {
return 301 https://$host$request_uri;
}
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
error_page 497 https://$host$request_uri;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
}
4.3 载入配置
配置修改完毕后,执行标准命令验证并平滑重载:
nginx -t
# 确认显示:nginx: configuration file ... test is successful
nginx -s reload
5. 总结
在 Nginx 反代大模型上游 API服务时,401 Unauthorized 常见于 Header 信息的非标准截断。通过开启 underscores_in_headers on; 并显式声明 proxy_set_header Authorization $http_authorization;,可以确保鉴权令牌完好无损地送达后端。在实际运维中,善用 curl 绕过反代层进行端口直连,是快速隔离代理层故障与应用层故障的最佳工程实践。