رفع خطای ⁦HTTP 407 Proxy Authentication Required⁩

تاریخ انتشار:

18 دقیقه مطالعه

Acar Diveroli
نویسنده: Acar Diveroli
سمت چپ دروازه PROXY، کارت‌های NO AUTH و WRONG PASS پشت ضربدر قرمز می‌مانند؛ سمت راست کارت آبی Proxy-Authorization عبور می‌کند

پروکسی تازه‌خریده را در cURL می‌گذارید و پاسخ این است: 407 Proxy Authentication Required. همین سه رقم در پایتون به شکل Tunnel connection failed: 407، در گیت به شکل The requested URL returned error: 407 و در کروم به شکل پنجره نام کاربری‌ای ظاهر می‌شود که مدام برمی‌گردد. همه یک ریشه دارند: درخواست شما هرگز به سایت نرسیده است. پروکسی میان راه آن را پشت دروازه نگه داشته است.

این نوشته توضیح می‌دهد 407 در استاندارد HTTP چه معنایی دارد، با 401 چه فرقی دارد و پشت آن دروازه چه چیزی کم است. سپس جاهایی را که این خطا ظاهر می‌شود یکی‌یکی مرور می‌کند: اطلاعات ورود اشتباه یا ناقص در پروکسی خریداری‌شده، IP خانگی‌ای که در حالت احراز هویت با IP عوض شده، کاراکتر خاص در رمز، کرومی که قالب user:pass@ را نمی‌پذیرد، پروکسی‌های NTLM و Kerberos در شبکه‌های سازمانی، و اینکه اطلاعات ورود در cURL، پایتون، Node.js، npm، pip، گیت و داکر کجا نوشته می‌شود. همه نمونه‌کدها را در 7 اکتبر 2026 روی یک پروکسی آزمایشی محلی اجرا کردیم که نام کاربری و رمز می‌خواهد.

معنای ⁦HTTP 407 Proxy Authentication Required⁩ چیست؟

پاسخ 407 یعنی پروکسی می‌گوید «پیش از آنکه این را جلو ببرم، ثابت کن کیستی». استاندارد HTTP، یعنی ⁦RFC 9110⁩، این کد را در بخش ⁦15.5.8⁩ تعریف می‌کند: 407 شبیه 401 است، اما نشان می‌دهد کلاینت برای استفاده از پروکسی در این درخواست باید خودش را احراز هویت کند. پروکسی باید هدر Proxy-Authenticate را همراه با چالشی (challenge) بفرستد که برای همان پروکسی معتبر است، و کلاینت می‌تواند درخواست را با هدر Proxy-Authorization تازه یا جایگزین تکرار کند.

در عمل، این تبادل میان همین دو هدر می‌گذرد. پروکسی روش را با Proxy-Authenticate: Basic realm="x" اعلام می‌کند؛ در Basic، که رایج‌ترین روش است، کلاینت نام کاربری و رمز را به شکل user:pass کنار هم می‌گذارد، رشته را با Base64 کدگذاری می‌کند و هدر Proxy-Authorization: Basic dXNlcjpwYXNz را اضافه می‌کند. Base64 رمزنگاری نیست؛ هر کسی که dXNlcjpwYXNz را رمزگشایی کند user:pass را می‌خواند، پس امنیت اطلاعات ورود به شبکه قابل‌اعتماد یا TLS در مسیر تا پروکسی وابسته است.

یک جزئیات استاندارد هنگام عیب‌یابی به کار می‌آید: هدر Proxy-Authorization را نخستین پروکسی‌ای که آن را دریافت می‌کند مصرف می‌کند و به سایت نمی‌فرستد. پروکسی رمز شما را می‌بیند، سایت نمی‌بیند. وقتی در شبکه سازمانی چند پروکسی پشت سر هم قرار دارند، هر کدام اطلاعات ورود خودش را می‌خواهد و مقدار realm در Proxy-Authenticate می‌گوید 407 را کدام‌یک فرستاده است.

تفاوت 407 و 401 چیست؟

این دو کد یک سازوکار را در دو طرف متفاوت اجرا می‌کنند. ⁦401 Unauthorized⁩ یعنی خود سایت اطلاعات ورود می‌خواهد: پاسخ هدر WWW-Authenticate دارد، کلاینت با Authorization جواب می‌دهد و مشکل میان شما و سایت است. در 407 همین گفت‌وگو با پروکسی انجام می‌شود، با هدرهای Proxy-Authenticate و Proxy-Authorization، و سایت اصلاً درخواست را ندیده است.

همین تفاوت تعیین می‌کند کجا را بگردید. پس از 401 حساب، کلید API یا توکن خود را در سایت بررسی می‌کنید. پس از 407 هیچ‌چیزِ سایت اهمیت ندارد؛ نام کاربری، رمز یا فهرست IP در پنل پروکسی، یا حسابی که مدیر شبکه به شما داده، همان جایی است که مشکل در آن است. ممکن است هر دو را پشت سر هم هم بگیرید: اول پروکسی با 407 رد می‌شود، بعد سایت 401 برمی‌گرداند.

407 گام‌به‌گام چگونه رخ می‌دهد؟

برای تماشای جریان، یک پروکسی آزمایشی 40 خطی با Node.js نوشتیم. این پروکسی به هر درخواستی که هدر Proxy-Authorization آن با user:pass نخواند، 407 و Proxy-Authenticate: Basic realm="x" برمی‌گرداند، درخواست‌های درست را جلو می‌برد، همین قانون را روی تونل CONNECT مخصوص HTTPS اعمال می‌کند و هر درخواست را ثبت می‌کند. برای یک صفحه HTTPS، لاگ این‌طور خوانده می‌شد:

  1. کلاینت CONNECT site.com:443 را به پروکسی می‌فرستد و تونلی به سایت می‌خواهد. برای آدرس http:// خود درخواست را می‌فرستد (GET http://site.com/ …).
  2. اگر درخواست Proxy-Authorization نداشته باشد، پروکسی 407 Proxy Authentication Required را با Proxy-Authenticate: Basic realm="x" برمی‌گرداند و چیزی باز نمی‌کند. خط لاگ این است: CONNECT site.com:443 Proxy-Authorization: (none).
  3. کلاینت هدر را اضافه می‌کند و درخواست را تکرار می‌کند: Proxy-Authorization: Basic dXNlcjpwYXNz. بسیاری از ابزارها این کار را در همان تلاش اول انجام می‌دهند؛ cURL با -U هرگز منتظر 407 نمی‌ماند.
  4. پروکسی مقدار را بررسی می‌کند. اگر درست باشد، تونل را باز می‌کند و 200 Connection Established برمی‌گرداند؛ از اینجا به بعد ترافیک TLS از تونل می‌گذرد. اگر اشتباه باشد، گام 2 را تکرار می‌کند؛ رمز اشتباه و رمز ناموجود برای پروکسی همان 407 است.
  5. سایت تازه حالا درخواست را می‌بیند و پاسخ خودش را می‌دهد (200، 404، 401…). در هدرهایی که به سایت رسیده Proxy-Authorization وجود ندارد؛ پروکسی آن را مصرف کرده است.

با cURL نخستین گام این جریان با یک فرمان دیده می‌شود. برای یک آدرس HTTP ساده، درخواست بدون اطلاعات ورود این پاسخ را گرفت:

bash
curl -i -x http://pr.proxynet.io:8000 http://example.com/
text
HTTP/1.1 407 Proxy Authentication Required
Proxy-Authenticate: Basic realm="x"
Connection: close

برای آدرس HTTPS، cURL به جای آن خطای خودش را گزارش می‌کند: curl: (56) CONNECT tunnel failed, response 407. هر دو همان هدرِ ناموجودند.

چرا خطای 407 رخ می‌دهد؟

علت‌ها در دو گروه جا می‌گیرند: اطلاعات ورود پروکسی‌ای که خریده‌اید، و اطلاعات ورود پروکسی‌ای که شبکه شما اداره می‌کند. متن خطا در هر دو یکسان است؛ جای رفع آن یکسان نیست.

علتنشانهراه‌حل
اطلاعات ورود اصلاً فرستاده نمی‌شودخط Proxy-Authorization وجود ندارد، 407 در همان درخواست اولاز گزینه اطلاعات ورود پروکسی در ابزار استفاده کنید (-U، proxies=، token)
نام کاربری یا رمز اشتباه استهدر هست، باز هم 407از پنل کپی کنید؛ فاصله و بزرگی و کوچکی حروف را بررسی کنید
@، : یا # در رمزخطای «bad hostname» در URL یا 407در URL به شکل %40، %3A، %23 کدگذاری کنید یا گزینه جداگانه به کار ببرید
احراز هویت با IP، IP خانگی عوض شدهتنظیم دیروز امروز کار نمی‌کندIP تازه را در پنل اضافه کنید یا به نام کاربری و رمز بروید
کروم user:pass@ را در آدرس نادیده می‌گیردERR_NO_SUPPORTED_PROXIES یا پنجره ورودpage.authenticate() در Puppeteer، پنجره ورود در مرورگر
پروکسی سازمانی NTLM یا Kerberos می‌خواهدProxy-Authenticate: Negotiate یا NTLMحساب دامنه با --proxy-negotiate؛ NTLM از نسخه ⁦8.20⁩ در بیلدهای cURL خاموش است
زنجیره‌ای از پروکسی‌هاپنجره ورود مدام برمی‌گرددهر پروکسی اطلاعات ورود خودش را می‌خواهد؛ از تیم شبکه بپرسید

407 را در پروکسی خریداری‌شده چگونه رفع کنید؟

بیشتر خطاهای 407 از شکاف کوچکی میان آنچه از پنل کپی کرده‌اید و قالبی که ابزار انتظار دارد می‌آید. اول ببینید اطلاعات ورود اصلاً فرستاده می‌شود یا نه: اگر curl -v خطی به شکل > Proxy-Authorization: نشان نمی‌دهد، مشکل در قالب است. اگر خط هست و پاسخ باز هم 407 است، مقدار اشتباه است یا حساب مشکلی دارد؛ در آزمایش ما پروکسی به رمز اشتباه دقیقاً همان پاسخی را داد که به نبودِ رمز.

کاراکترهای خاص. آدرس پروکسی یک URL به شکل http://user:pass@host:port است و در URL علامت @ اطلاعات کاربر را از نام میزبان جدا می‌کند. اگر رمز شما p@ss باشد، آدرس دو علامت @ دارد؛ ⁦cURL 8.5⁩ آن را با curl: (5) Unsupported proxy syntax … Bad hostname رد کرد. با %40 به جای @ (یعنی http://user:p%40ss@host:port) پروکسی user:p@ss را رمزگشایی کرد و درخواست رد شد. برای : از %3A، برای # از %23 و برای / از %2F استفاده کنید. Python Requests آدرس کدگذاری‌نشده را هم پذیرفت، چون URL را از آخرین @ جدا کرد، اما کدگذاری در همه ابزارها یکسان جواب می‌دهد. گزینه‌هایی که اطلاعات ورود را بیرون از URL می‌گیرند (curl -U "user:p@ss" و HTTPProxyAuth("user", "p@ss") در Requests) به کدگذاری نیاز ندارند؛ هر دو با رمز خام عبور کردند.

احراز هویت با IP. اگر به جای رمز، آدرس IP خود را در پنل ثبت کرده‌اید، پروکسی به آدرسی نگاه می‌کند که اتصال از آن می‌آید. در اتصال خانگی، IP عمومی با راه‌اندازی دوباره مودم یا چرخش استخر آدرس اپراتور عوض می‌شود و تنظیمی که دیروز کار می‌کرد امروز 407 برمی‌گرداند. IP فعلی خود را با آدرس ذخیره‌شده در پنل مقایسه کنید. اگر آدرس شما زیاد عوض می‌شود، نام کاربری و رمز روش کم‌دردسرتری است؛ راهنمای احراز هویت پروکسی ما این دو روش را مقایسه می‌کند.

پارامترهای نشست. پارامترهایی که برای نشست چسبنده یا انتخاب کشور به نام کاربری اضافه می‌شوند، مثل user-session-abc-country-tr، بخشی از نام کاربری‌اند؛ غلط املایی یا پارامتر پشتیبانی‌نشده در برخی ارائه‌دهندگان به شکل 407 برمی‌گردد. اول با user:pass ساده امتحان کنید و پارامترها را یکی‌یکی برگردانید. در پلن پروکسی مسکونی این پارامترها طول نشست و کشور خروجی را تعیین می‌کنند، پس جدا کردن خطای پارامتر از خطای رمز در وقت صرفه‌جویی می‌کند.

407 را در پروکسی سازمانی چگونه رفع کنید؟

در شبکه شرکت یا دانشگاه، پروکسی را شما تنظیم نکرده‌اید؛ سیستم‌عامل آن را از فایل پیکربندی خودکار (PAC) یا سیاست گروهی می‌گیرد و اطلاعات ورود معمولاً حساب دامنه شماست. این پروکسی‌ها اغلب به جای Basic، هدر Proxy-Authenticate: Negotiate (یعنی Kerberos) یا NTLM می‌خواهند. مرورگرها و Office از حساب ویندوزی که با آن وارد شده‌اید استفاده می‌کنند و بی‌سروصدا عبور می‌کنند؛ ابزارهای خط فرمان و اسکریپت‌ها چنین نمی‌کنند و 407 برمی‌گردانند.

cURL اجازه می‌دهد روش را انتخاب کنید: --proxy-negotiate -U : از هویت نشست برای Kerberos استفاده می‌کند و --proxy-anyauth از میان روش‌هایی که پروکسی ارائه می‌دهد روش مناسب را برمی‌گزیند. در آزمایش ما، cURL با --proxy-anyauth اول یک درخواست بدون اطلاعات ورود فرستاد، 407 و Proxy-Authenticate: Basic آن را خواند و سپس با Basic تکرار کرد؛ یک رفت‌وبرگشت اضافه، اما وقتی نمی‌دانید پروکسی چه می‌خواهد به کار می‌آید. NTLM داستان جداگانه‌ای است. پروژه curl از نسخه ⁦8.20.0⁩ (29 آوریل 2026) NTLM را به‌طور پیش‌فرض در بیلد خاموش می‌کند و قصد دارد آن را به‌کلی حذف کند؛ دلیلش رمزنگاری ضعیف این روش، ناسازگاری آن با HTTP/2 و HTTP/3 و کنار گذاشتن NTLM از سوی خود مایکروسافت است. با ⁦cURL 8.20⁩ یا جدیدتر، --proxy-ntlm در بیشتر توزیع‌ها دیگر کار نمی‌کند؛ اگر پروکسی فقط NTLM می‌پذیرد، از تیم شبکه بخواهید Negotiate را فعال کند. ⁦cURL 8.5⁩ ما هنوز با --proxy-ntlm نخستین پیام NTLM را فرستاد؛ پروکسی آزمایشی ما که فقط Basic می‌شناسد دوباره 407 داد.

پنجره‌ای که در ویندوز مدام باز می‌شود. تنظیمات پروکسی ویندوز فقط آدرس را نگه می‌دارد، نه نام کاربری و رمز را؛ هر برنامه وقتی 407 می‌گیرد خودش اطلاعات ورود را می‌پرسد. اگر پنجره بسته می‌شود و بلافاصله دوباره باز می‌شود، اطلاعات ورود رد شده است: پس از تغییر اخیر رمز، مدیر اطلاعات کاربری ویندوز (Credential Manager) رمز قدیمی ذخیره‌شده را آن‌قدر امتحان می‌کند تا آن را پاک کنید. یک یادداشت پشتیبانی قدیمی مایکروسافت علت دیگری را توضیح می‌دهد: وقتی چند پروکسی که NTLM می‌خواهند پشت سر هم باشند، اولی رد می‌شود، دومی 407 برمی‌گرداند و پنجره دوباره ظاهر می‌شود؛ راه‌حل پیشنهادی فعال کردن Negotiate با Kerberos است که کار تیم شبکه است.

چرا کروم و Puppeteer خطای 407 را جور دیگری نشان می‌دهند؟

کروم از نام کاربری و رمزی که در آدرس پروکسی نوشته شده استفاده نمی‌کند. مستندات پروکسی Chromium این را صریح می‌گوید: مرورگر اطلاعات ورود جاسازی‌شده در تنظیمات پروکسی را پیاده نمی‌کند و احراز هویت پروکسی از جریان عادی می‌گذرد، یعنی پنجره‌ای که پس از 407 باز می‌شود. پروکسی‌های HTTP از Basic، Digest، Negotiate و NTLM پشتیبانی می‌کنند؛ SOCKS5 هیچ احراز هویتی ندارد. بنابراین نوشتن user:pass@ در --proxy-server هیچ کاری نمی‌کند. در آزمایش نوشته Puppeteer ما در 6 اکتبر، ⁦Chrome 154⁩ کل مقدار را با net::ERR_NO_SUPPORTED_PROXIES رد کرد؛ وقتی اطلاعات ورود هیچ‌جا داده نشد، نخستین ناوبری با net::ERR_INVALID_AUTH_CREDENTIALS شکست خورد. در این نسخه 407 هرگز به کاربر نمی‌رسد؛ کروم آن را به کد خطای خودش تبدیل می‌کند.

راه‌حل این است که اطلاعات ورود را همان‌جایی بگذارید که پاسخ مرورگر به 407 ساخته می‌شود. در Puppeteer این page.authenticate() است و باید پیش از نخستین page.goto() بیاید:

js
import puppeteer from "puppeteer";

const browser = await puppeteer.launch({
  args: ["--proxy-server=http://pr.proxynet.io:8000"], // no credentials in the address
});
const page = await browser.newPage();
await page.authenticate({ username: "user", password: "pass" }); // the answer to the 407
await page.goto("https://httpbin.org/ip");

بر اساس مستندات Puppeteer، این فراخوانی در پس‌زمینه رهگیری درخواست را روشن می‌کند و با دادن null خاموش می‌شود. اطلاعات ورود به بافتار مرورگر (browser context) تعلق دارد، نه به صفحه؛ همه صفحه‌های همان بافتار از نخستین مقدار واردشده استفاده می‌کنند. در کرومی که دستی کار می‌کنید، آن را در پنجره‌ای که پس از 407 باز می‌شود تایپ می‌کنید.

اطلاعات ورود پروکسی را در هر ابزار چگونه می‌دهید؟

هر ابزار اطلاعات ورود را در جای متفاوتی می‌گیرد. همه نمونه‌ها از پروکسی آزمایشی محلی گذشتند؛ آدرس را pr.proxynet.io:8000 و اطلاعات ورود را user:pass نشان می‌دهیم.

cURL. اطلاعات ورود یا در آدرس می‌رود یا در گزینه‌ای جداگانه؛ -U و --proxy-user یک چیزند. cURL به‌طور پیش‌فرض از Basic استفاده می‌کند و اطلاعات ورود را در همان درخواست اول می‌فرستد.

bash
# credentials in a separate option: no encoding needed for special characters
curl -x http://pr.proxynet.io:8000 -U user:pass https://httpbin.org/ip

# credentials in the address: %40 for @, %3A for :
curl -x http://user:p%40ss@pr.proxynet.io:8000 https://httpbin.org/ip

# see which scheme the proxy expects
curl -v -x http://pr.proxynet.io:8000 https://httpbin.org/ip 2>&1 | grep -i proxy-auth

متغیرهای محیطی همان آدرس را می‌گیرند: export HTTPS_PROXY=http://user:pass@pr.proxynet.io:8000، همراه با HTTP_PROXY برای HTTP ساده و NO_PROXY برای میزبان‌هایی که باید دور زده شوند. بقیه گزینه‌های پروکسی cURL در راهنمای cURL با پروکسی ما آمده است.

Python Requests. اطلاعات ورود در آدرسِ درون دیکشنری proxies می‌رود، یا در HTTPProxyAuth که هدر Proxy-Authorization را اضافه می‌کند. مستندات Requests قالب http://user:password@host/ را تعریف می‌کند و هشدار می‌دهد که نگه داشتن نام کاربری و رمز در متغیر محیطی یا فایلی که در کنترل نسخه است ریسک امنیتی است.

python
import requests
from requests.auth import HTTPProxyAuth

PROXY = "http://user:pass@pr.proxynet.io:8000"
proxies = {"http": PROXY, "https": PROXY}

r = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=15)
print(r.status_code, r.json())

# credentials apart from the address: no encoding needed for special characters
auth = HTTPProxyAuth("user", "pass")
r = requests.get("https://httpbin.org/ip", proxies={"https": "http://pr.proxynet.io:8000"}, auth=auth, timeout=15)

در آزمایش ما با ⁦Requests 2.34⁩ هر دو مسیر از پروکسی گذشتند. شکل خطا به مقصد بستگی دارد: برای آدرس HTTPS، درخواست بدون اطلاعات ورود استثنای requests.exceptions.ProxyError را با پیام Tunnel connection failed: 407 Proxy Authentication Required بالا آورد؛ برای آدرس HTTP ساده استثنایی در کار نبود، r.status_code برابر 407 بود و r.headers["Proxy-Authenticate"] چالش را حمل می‌کرد. اسکریپتی که فقط استثناها را می‌گیرد، 407 را در آدرس‌های HTTP از دست می‌دهد؛ به بررسی r.status_code == 407 نیاز دارد. HTTPProxyAuth فقط هدر Proxy-Authorization را اضافه می‌کند؛ ورود به خود سایت از HTTPBasicAuth می‌گذرد. برای فرستادن یک سری درخواست POST از یک نشست، proxies را به تنظیم Session در راهنمای POST و JSON با Requests ما اضافه کنید.

Node.js و undici. تابع fetch داخلی Node با کلاس ProxyAgent از undici از پروکسی می‌گذرد. اطلاعات ورود در uri می‌رود یا به شکل مقدار آماده هدر در گزینه token؛ مستندات ProxyAgent در undici هر دو را توضیح می‌دهد و یادآور می‌شود که اطلاعات ورود درون URI پیش از کدگذاری Base64 از کدگذاری URL خارج می‌شود.

js
import { fetch, ProxyAgent } from "undici";

const agent = new ProxyAgent({
  uri: "http://pr.proxynet.io:8000",
  token: `Basic ${Buffer.from("user:pass").toString("base64")}`, // the Proxy-Authorization value
});

const res = await fetch("https://httpbin.org/ip", { dispatcher: agent });
console.log(res.status, await res.json());

با ⁦undici 8.10⁩، گزینه token و uri حاوی user:p%40ss نتیجه یکسانی دادند. درخواست بدون اطلاعات ورود با TypeError: fetch failed شکست خورد؛ دلیل واقعی در error.cause به شکل InvalidArgumentError: Proxy Authentication Required (407) نشسته بود و برای آدرس HTTPS فقط می‌گفت Request was cancelled. Node متغیرهای محیطی پروکسی را هم خودبه‌خود نمی‌خواند: با HTTPS_PROXY تنظیم‌شده، fetch همچنان مستقیم وصل شد. متغیر NODE_USE_ENV_PROXY=1 که در ⁦Node 22.21⁩ و ⁦24.0⁩ معرفی شد این را روشن می‌کند؛ در آزمایش ما با یک هشدار آزمایشی کار کرد.

npm، pip، گیت و داکر. هر چهار ابزار همان قالب آدرس را می‌پذیرند و اطلاعات ورود درون آدرس می‌رود.

bash
# npm: persistent setting (the HTTPS_PROXY environment variable is read too)
npm config set proxy http://user:pass@pr.proxynet.io:8000
npm config set https-proxy http://user:pass@pr.proxynet.io:8000

# pip: --proxy for one command, proxy = in pip.conf for good
pip install --proxy http://user:pass@pr.proxynet.io:8000 requests

# Git: format [protocol://][user[:password]@]proxyhost[:port]
git config --global http.proxy http://user:pass@pr.proxynet.io:8000
git config --global http.proxyAuthMethod basic   # anyauth, basic, digest, negotiate, ntlm

برای کلاینت داکر، تنظیم در شیء proxies.default (با کلیدهای httpProxy، httpsProxy و noProxy) در ~/.docker/config.json می‌رود؛ مستندات داکر یادآور می‌شود این مقدارها به شکل متن ساده در پیکربندی کانتینر ذخیره می‌شوند و از طریق API راه دور قابل خواندن‌اند. در آزمایش ما گیت بدون اطلاعات ورود گفت fatal: unable to access '…': The requested URL returned error: 407 و با آن عبور کرد. pip در خروجی پیش‌فرض 407 را پشت Could not find a version that satisfies the requirement پنهان کرد؛ علت واقعی با pip -vvv پیدا شد: 407 Client Error: Proxy Authentication Required.

ابزار407 را چگونه نشان می‌دهداطلاعات ورود کجا می‌رود
cURLCONNECT tunnel failed, response 407-U user:pass یا آدرس
Python RequestsProxyError در HTTPS، status_code == 407 در HTTPآدرس در proxies= یا HTTPProxyAuth
Node undicifetch failed، دلیل در causetoken یا uri در ProxyAgent
Chrome / PuppeteerERR_INVALID_AUTH_CREDENTIALS، پنجره ورودpage.authenticate()
GitThe requested URL returned error: 407آدرس در http.proxy
pipفقط با -vvv--proxy یا pip.conf

IP ثابت چگونه جلوی 407 را می‌گیرد؟

در احراز هویت با IP، رایج‌ترین علت 407 عوض شدن آدرس است. از یک IP عمومی ثابت مثل سرور ابری یا خط اداری، فهرست را یک بار پر می‌کنید و هیچ رمزی در کد حمل نمی‌کنید؛ از اتصال خانگی یا شبکه‌های متغیر، نام کاربری و رمز وقفه کمتری ایجاد می‌کند.

ثبات در سمت پروکسی هم مهم است. در پلن پروکسی ISP IP خروجی عوض نمی‌شود، پس یک آدرس در فهرست مجاز سایت یا سیستم سازمانی ثبت می‌شود و در آن سمت هم مشکل اطلاعات ورود پیش نمی‌آید.

اشتباهات رایج

  • جست‌وجوی خطا در سایت. درخواستی که 407 گرفته هرگز به سایت نرسیده است؛ حساب، کوکی یا کلید API سایت نتیجه را عوض نمی‌کند.
  • نوشتن رمز کدگذاری‌نشده در URL. رمزی که @ دارد آدرس را خراب می‌کند؛ از %40 یا گزینه جداگانه اطلاعات ورود استفاده کنید.
  • گذاشتن user:pass@ در فلگ کروم. Chromium آن را نادیده می‌گیرد؛ در Puppeteer از page.authenticate() و در کار دستی از پنجره ورود استفاده کنید.
  • گرفتن فقط استثناها. Requests برای آدرس HTTP ساده هیچ استثنایی نمی‌اندازد و یک شیء پاسخ با 407 برمی‌گرداند؛ کد وضعیت را بررسی کنید.
  • اعتماد به IP قدیمی. در احراز هویت با IP، تنظیم دیروز شاید با آدرس امروز نخواند.
  • نوشتن اطلاعات ورود در اسکریپت یا مخزن. هم مستندات Requests و هم داکر این را ریسک می‌دانند؛ از متغیر محیطی محدود به نشست یا مدیر رازها استفاده کنید.
  • انتظار NTLM پس از ⁦cURL 8.20⁩. NTLM در بیلد خاموش است؛ در پروکسی‌های سازمانی Negotiate (یعنی Kerberos) بخواهید.

راهنمای انتخاب

وضعیت شماچه کنید
در curl -v خبری از Proxy-Authorization نیستاطلاعات ورود را با -U یا در آدرس اضافه کنید
هدر هست، باز هم 407رمز را دوباره از پنل کپی کنید؛ user:pass ساده را امتحان کنید
@، : یا # در رمز%40، %3A، %23 در URL، یا گزینه جداگانه اطلاعات ورود
احراز هویت با IP، آدرس عوض شدهIP تازه در پنل؛ اگر زیاد عوض می‌شود به نام کاربری و رمز بروید
کروم یا Puppeteerpage.authenticate()؛ اطلاعات ورود در فلگ نه
شبکه شرکت، Proxy-Authenticate: Negotiate--proxy-negotiate -U : یا حساب دامنه؛ Kerberos به جای NTLM
پنجره در ویندوز نمی‌رودرمز قدیمی را در Credential Manager پاک کنید؛ درباره پروکسی‌های زنجیره‌ای از تیم شبکه بپرسید

پرسش‌های متداول

خطای ⁦HTTP 407⁩ یعنی چه؟

یعنی پروکسی پیش از جلو بردن درخواست شما اطلاعات ورود می‌خواهد و درخواست یا هیچ اطلاعاتی نداشته یا اطلاعات اشتباه داشته است. هدر Proxy-Authenticate در پاسخ روش مورد انتظار را می‌گوید؛ راه‌حل، افزودن هدر Proxy-Authorization با مقدار درست است.

تفاوت 407 و 401 چیست؟

در 401 خود سایت اطلاعات ورود می‌خواهد، با WWW-Authenticate و Authorization؛ در 407 پروکسی میان راه می‌خواهد، با Proxy-Authenticate و Proxy-Authorization. درخواستی که 407 گرفته هرگز به سایت نرسیده است.

چرا با اینکه رمز پروکسی‌ام درست است 407 می‌گیرم؟

سه علت رایج: کاراکتر خاص رمز در URL کدگذاری نشده، ابزار اطلاعات ورود را از آدرس نمی‌خواند (کروم همین‌طور کار می‌کند)، یا حساب در حالت احراز هویت با IP است و آدرس فعلی شما در فهرست نیست. با curl -v ببینید اصلاً خط Proxy-Authorization فرستاده می‌شود یا نه.

رمزی که علامت @ دارد را چگونه در آدرس پروکسی بنویسم؟

@ را با %40 جایگزین کنید: http://user:p%40ss@host:port. با همین منطق برای : از %3A و برای # از %23 استفاده کنید. گزینه‌های جداگانه مثل -U "user:p@ss" در cURL یا HTTPProxyAuth("user", "p@ss") در Requests به کدگذاری نیاز ندارند.

نام کاربری و رمز پروکسی را در کروم کجا وارد کنم؟

تنظیمات پروکسی کروم فیلد نام کاربری ندارد و مرورگر بخش user:pass@ آدرس را نادیده می‌گیرد. اطلاعات ورود را در پنجره‌ای تایپ می‌کنید که پس از نخستین 407 باز می‌شود؛ در ابزارهای خودکارسازی مثل Puppeteer، فراخوانی page.authenticate({ username, password }) جای آن پنجره را می‌گیرد.

در پروکسی شرکتم 407 می‌گیرم. چه کنم؟

پروکسی به احتمال زیاد NTLM یا Kerberos (یعنی Negotiate) می‌خواهد و حساب دامنه شما را انتظار دارد. در cURL گزینه --proxy-negotiate -U : را امتحان کنید؛ چون NTLM از نسخه ⁦8.20⁩ در بیلدهای cURL خاموش است، برای پروکسی‌ای که فقط NTLM می‌پذیرد از تیم شبکه بخواهید Negotiate را فعال کند.

خلاصه

⁦HTTP 407 Proxy Authentication Required⁩ می‌گوید پروکسی‌ای که درخواست شما را جلو می‌برد اطلاعات ورود می‌خواهد؛ سایت از این ماجرا بی‌خبر است. راه‌حل در هر ابزار همان هدر با مقدار درست است: -U در cURL، آدرس proxies= یا HTTPProxyAuth در Requests، token در undici، page.authenticate() در Puppeteer و آدرس http://user:pass@host:port در npm، pip، گیت و داکر. @ در رمز به %40 تبدیل می‌شود، احراز هویت با IP آدرس فعلی شما را در فهرست لازم دارد و شبکه‌های سازمانی به جای Basic با Negotiate حرف می‌زنند، در حالی که NTLM از نسخه ⁦8.20⁩ در بیلدهای cURL خاموش است. برای پلن‌هایی که با نام کاربری و رمز یا فهرست IP کار می‌کنند، سرویس‌های پروکسی ما را ببینید.

پرسش از ChatGPTپرسش از Claude