407 代理身份验证要求:每个原因及其解决方法
HTTP 407 只有一个含义:前面的代理拒绝了您的凭据。这个单一事实消除了大多数错误的方向——这里是剩下的地图。
HTTP 407 代理身份验证要求只有一个含义,比大多数人想象的要狭窄:一个位于您和互联网之间的代理拒绝了请求,因为它缺乏有效的凭据针对代理本身。目标网站从未被联系。它从未看到您的请求,从未做出决定,也不可能是原因。因此,修复 407 总是意味着修复您的代理配置——可以出错的事情列表很短且完全可枚举。本指南涵盖了整个列表,包括最容易让人困惑的工具特定修复。
首先阅读 Proxy-Authenticate 头
根据 HTTP 规范 (RFC 9110),407 必须伴随一个描述如何进行身份验证的Proxy-Authenticate头——通常是类似Proxy-Authenticate: Basic realm="Access to internal site"的内容。然后,您的客户端应重复请求并带有Proxy-Authorization头。这个配对值得记住,因为它是 407 与其邻居的区别:401 来自源服务器,并将WWW-Authenticate与Authorization配对,而407来自中介,并使用Proxy-前缀版本。如果您盯着WWW-Authenticate头,您正在调试错误的跳跃。
# See exactly which hop is refusing you, and what scheme it wants
curl -v -x http://USER:PASS@gate.quantumproxies.io:8000 https://httpbin.org/ip
# Response you are looking for on failure:
# HTTP/1.1 407 Proxy Authentication Required
# Proxy-Authenticate: Basic realm="..."
#
# Response you want on success: your exit IP, not your own
# {"origin": "203.0.113.45"}
如果curl -x带凭据返回您的出口 IP,代理和凭据都没问题——您在应用程序中仍然看到的任何 407 都是该应用程序自己的配置,而不是代理的。这个简单的测试在大约十秒钟内将问题一分为二。
原因 1:凭据缺失、错误或位置错误
最常见的原因也是最无聊的。凭据属于代理 URL,在主机之前,以user:pass@host:port形式——客户端库从中构建Proxy-Authorization头。从仪表板复制一个端点而没有凭据,或者粘贴您的帐户密码而不是代理密码(它们通常不同),会在每个请求上立即产生永久的 407。
import requests
proxy = "http://USER:PASS@gate.quantumproxies.io:8000"
proxies = {"http": proxy, "https": proxy}
r = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=15)
print(r.status_code, r.json()) # 200 and the exit IP = auth is correct
也要检查端口。提供商为旋转和粘性端点以及 HTTP 与 SOCKS5 暴露不同的端口;即使凭据有效,命中错误的端口仍可能返回 407,因为该监听器期望不同的身份格式。如果您不确定您使用的是哪个协议,我们关于SOCKS5 与 HTTP 代理的解释说明了区别。
原因 2:从未进行百分比编码的特殊字符
这一个让人们浪费了整个下午。代理 URL 是一个 URL,因此用户名或密码中的任何保留字符都必须进行百分比编码,否则解析器会在错误的位置拆分字符串。包含@的密码会提前结束用户信息部分,您的客户端尝试连接到不存在的主机;:在错误的位置将用户名与密码分开。
@变为%40——最常见的罪魁祸首,因为电子邮件被用作用户名。:变为%3A——否则它会被读取为用户名/密码分隔符。#变为%23——其后的所有内容被视为片段并被静默丢弃。/变为%2F,?变为%3F——两者都结束了权限部分。- 一个字面上的空格变为
%20。如果您的密码中有一个,请更改它。
from urllib.parse import quote
user = quote("team@example.com", safe="") # team%40example.com
pwd = quote("p@ss:w#rd", safe="") # p%40ss%3Aw%23rd
proxy = f"http://{user}:{pwd}@gate.quantumproxies.io:8000"

原因 3:白名单身份验证和移动的 IP
大多数提供商支持两种身份验证模式:URL 中的凭据或 IP 白名单,您在仪表板中授权服务器的公共地址,并且不发送任何凭据。QuantumProxies 支持两者。故障模式是特定且非常可识别的:一切工作了几周,然后每个请求开始返回 407 而没有代码更改。这是您的公共 IP 更改——办公室的 DHCP 租约续约,云重新部署后的新 NAT 网关,移动网络共享,或每个作业获取新地址的 CI 运行器。
在调试其他任何内容之前确认这一点:使用curl -sS https://api.ipify.org获取您当前的公共地址,将其与白名单进行比较,如果不同则重新添加。如果您的出口 IP 不稳定——CI 运行器和自动缩放组很少稳定——将该环境切换到user:pass身份验证,它随配置而不是网络一起传输。这个陷阱的另一半是混合模式:一些网关在仅白名单端点上拒绝凭据,因此发送两者可能会失败,而发送都不发送则成功。
原因 4:HTTPS 通过 CONNECT 隧道
仅在https:// URL 上出现的 407,通常作为 Python 错误OSError: Tunnel connection failed: 407 Proxy Authentication Required,具有结构性原因。普通 HTTP 请求由代理转发,但 HTTPS 请求首先通过CONNECT请求打开一个隧道——而该 CONNECT 携带自己的Proxy-Authorization头。如果您的配置仅设置了 HTTP 代理,或在一个方案上设置了凭据而不是另一个,隧道将匿名尝试并在 TLS 开始之前被拒绝。
规则很简单:始终使用相同的凭据配置两个方案。在 Python 中,这意味着proxies字典中的两个键;在 shell 中,这意味着HTTP_PROXY和HTTPS_PROXY;在 npm 中,这意味着proxy和https-proxy。请注意,HTTPS_PROXY几乎总是采用http://方案——该方案描述了您如何与代理通信,而不是您通过它获取的内容。
// Node 18+ with undici: one dispatcher covers http and https targets
import { ProxyAgent, fetch } from "undici";
const dispatcher = new ProxyAgent(
"http://USER:PASS@gate.quantumproxies.io:8000"
);
const res = await fetch("https://httpbin.org/ip", { dispatcher });
console.log(res.status, await res.json());
原因 5:工具有自己的代理配置
环境变量并非通用。许多工具读取自己的配置文件并完全忽略 shell,这产生了令人恼火的状态,即curl工作而您的构建不工作。一个长期存在的 GitHub Desktop 问题是教科书式的例子:一个开发人员在公司代理后面设置了.gitconfig和环境中的代理,但登录仍然失败,出现 407 和net::ERR_TUNNEL_CONNECTION_FAILED——因为 git 配置仅对 git 进行身份验证,而进行 OAuth 流程的嵌入式浏览器没有自己的代理凭据。每个子系统都需要单独告知。
# shell-wide (respected by curl, wget, pip, most SDKs)
export HTTP_PROXY="http://USER:PASS@gate.quantumproxies.io:8000"
export HTTPS_PROXY="$HTTP_PROXY"
export NO_PROXY="localhost,127.0.0.1,.internal"
# npm - both keys, or https installs will 407
npm config set proxy "$HTTP_PROXY"
npm config set https-proxy "$HTTPS_PROXY"
# git
git config --global http.proxy "$HTTP_PROXY"
git config --global https.proxy "$HTTPS_PROXY"
# apt - /etc/apt/apt.conf.d/95proxies
# Acquire::http::Proxy "http://USER:PASS@gate.quantumproxies.io:8000";
# Acquire::https::Proxy "http://USER:PASS@gate.quantumproxies.io:8000";
- Postman——设置,代理,自定义代理配置,然后勾选代理身份验证并填写用户名和密码。系统代理切换不携带凭据。
- .NET / C#——读取"远程服务器返回错误:(407)"的
WebException意味着WebProxy没有Credentials;明确设置它们或使用默认网络凭据。 - Java——
http.proxyUser和http.proxyPassword系统属性,加上一个Authenticator,因为 JVM 不读取 shell 变量。 - 浏览器——修复凭据后,缓存的 407 可能会持续存在;在假设修复失败之前,强制重新加载或清除缓存。
- Docker——守护进程和构建都需要代理设置,并且它们在不同的地方配置。
在编辑所有这些文件时的一项安全提示:全局 git 或 npm 配置中的凭据最终以明文形式出现,嵌入密码的代理 URL 会泄漏到 shell 历史记录、CI 日志和错误跟踪中。在具有稳定地址的机器上,IP 白名单完全避免了秘密。

407 从来不是目标站点的错
值得重申,因为它可以让您免于追逐幽灵。如果您收到 407,无论旋转用户代理、添加头还是更改出口国家都无济于事——请求尚未离开您的代理。从目标站点来的阻止看起来不同:403 Forbidden表示站点拒绝了您,而429 Too Many Requests表示您速度太快。在编写任何代码之前,诊断您实际拥有的三者中的哪一个。如果 Python 抛出ProxyError或SSLError而不是干净的 407,我们的调试 Requests 中的 ProxyError指南涵盖了传输级别的故障。
常见问题解答
如何解决 407 代理身份验证要求?
将有效的凭据放在代理 URL 中作为http://user:pass@host:port,对任何保留字符进行百分比编码,并配置 HTTP 和 HTTPS 代理设置。如果您的提供商使用 IP 白名单,请授权您当前的公共 IP 并不发送凭据。在触及您的应用程序代码之前,使用curl -x对 IP 回显服务进行验证。
407 代理身份验证要求是什么意思?
这意味着中介代理因缺乏有效的代理凭据而拒绝了请求。响应包括一个Proxy-Authenticate头,命名方案,客户端应重试并带有Proxy-Authorization。它与 401 不同,401 来自目标服务器,而不是中间的代理。
如何修复 npm 错误 407?
设置两个键:npm config set proxy和npm config set https-proxy,每个都有完整的http://user:pass@host:port URL。注册表流量是 HTTPS,因此仅 HTTP 设置在 CONNECT 隧道处失败。对密码中的特殊字符进行百分比编码,并检查是否有项目级.npmrc覆盖您的全局配置。
为什么 Python 会引发 Tunnel connection failed: 407?
因为 HTTPS 请求打开了一个没有携带代理凭据的 CONNECT 隧道。将proxies字典中的http和https键都设置为相同的认证 URL。还要检查环境中的HTTP_PROXY或HTTPS_PROXY是否覆盖了您的字典——设置session.trust_env = False以排除这一点。
如何在 Postman 中设置代理身份验证?
打开设置,转到代理选项卡,启用自定义代理配置,输入主机和端口,然后勾选代理身份验证框并添加用户名和密码。依赖于系统代理切换是常见错误——它通过代理路由流量但从不提供凭据,因此每个请求都返回 407。
五个原因几乎涵盖了所有 407:缺少凭据、未编码的特殊字符、已更改的白名单 IP、未经身份验证的 CONNECT 隧道以及具有自身配置的工具。按此顺序处理它们,状态代码就会消失——然后您可以开始担心目标站点对您的看法。