Proxy Authentication Options in PHP cURL
Configure proxy credentials with the correct cURL options and handle the combined field's URL decoding without changing destination authentication.
Proxy authentication has its own cURL options. Setting CURLOPT_USERPWD for a website login does not configure the proxy's account, and selecting CURLOPT_HTTPAUTH does not select the proxy authentication method.
<?php
$user = 'proxy-user';
$password = getenv('PROXY_PASSWORD');
if ($password === false) {
throw new RuntimeException('Set PROXY_PASSWORD');
}
$ch = curl_init('https://example.com/');
curl_setopt_array($ch, [
CURLOPT_PROXY => 'http://203.0.113.10:8080',
CURLOPT_NOPROXY => '',
CURLOPT_PROXYUSERPWD =>
rawurlencode($user) . ':' . rawurlencode($password),
CURLOPT_PROXYAUTH => CURLAUTH_BASIC,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 15,
]);
$body = curl_exec($ch);
if ($body === false) {
throw new RuntimeException(curl_error($ch), curl_errno($ch));
}
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
Replace the documentation IP and use the credentials supplied for that proxy. Basic is selected deliberately in this example; use the method supported and approved for your service rather than assuming every endpoint needs it.
The combined field has an encoding rule
libcurl documents that CURLOPT_PROXYUSERPWD URL-decodes its username and password. The example encodes each component before joining them with the delimiter. This matters when a literal percent sequence or another special character belongs to the credential.
The separate proxy username and password options accept their respective values directly:
curl_setopt($ch, CURLOPT_PROXYUSERNAME, $user);
curl_setopt($ch, CURLOPT_PROXYPASSWORD, $password);
Use these as the alternative credential form before executing the request. Do not automatically apply the combined proxy field's decoding rule to CURLOPT_USERPWD; libcurl documents a difference between them.
Keep the authentication hops separate
CURLOPT_PROXYAUTH selects proxy authentication, while CURLOPT_HTTPAUTH selects HTTP authentication with the destination. If both parties require a login, configure the appropriate options for each rather than copying one credential into both places.
CURLAUTH_ANY allows negotiation and can add a challenge-response exchange before a method is selected. It does not prove that credentials are correct. Manually adding a Proxy-Authorization header as well can interfere with the library's authentication handling.
Basic credentials on a cleartext connection to the proxy are not protected by the website's later TLS tunnel. Check that transport separately when choosing how to use an authenticated service.