프록시 인증에는 별도 cURL 옵션이 있습니다. 웹사이트 로그인용 CURLOPT_USERPWD는 프록시 계정을 설정하지 않으며 CURLOPT_HTTPAUTH를 선택해도 프록시 인증 방식은 선택되지 않습니다.

<?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;

문서용 IP를 바꾸고 해당 프록시에 제공된 인증 정보를 사용하세요. 예시는 의도적으로 Basic을 선택했습니다. 모든 엔드포인트가 필요하다고 가정하지 말고 서비스가 지원하고 승인한 방식을 사용하세요.

결합 필드에는 인코딩 규칙이 있다

libcurl 문서에 따르면 CURLOPT_PROXYUSERPWD는 사용자 이름과 비밀번호를 URL 디코딩합니다. 예시는 각 구성 요소를 인코딩한 뒤 구분자로 연결합니다. 인증 정보에 문자 그대로의 퍼센트 시퀀스나 다른 특수 문자가 포함될 때 중요합니다.

별도 프록시 사용자 이름과 비밀번호 옵션은 각각의 값을 직접 받습니다.

curl_setopt($ch, CURLOPT_PROXYUSERNAME, $user);
curl_setopt($ch, CURLOPT_PROXYPASSWORD, $password);

요청 실행 전에 대체 인증 정보 형식으로 사용하세요. 결합 프록시 필드의 디코딩 규칙을 CURLOPT_USERPWD에 자동 적용하지 마세요. libcurl은 둘의 차이를 문서화합니다.

인증 구간을 분리하기

CURLOPT_PROXYAUTH는 프록시 인증을, CURLOPT_HTTPAUTH는 대상과의 HTTP 인증을 선택합니다. 양쪽 모두 로그인을 요구하면 같은 인증 정보를 두 곳에 복사하지 말고 각각 적절한 옵션을 설정하세요.

CURLAUTH_ANY는 협상을 허용하며 방식 선택 전에 챌린지-응답 교환을 추가할 수 있습니다. 인증 정보가 맞다는 증거는 아닙니다. Proxy-Authorization 헤더를 추가로 직접 넣으면 라이브러리의 인증 처리를 방해할 수 있습니다.

프록시에 평문으로 연결할 때의 Basic 인증 정보는 웹사이트의 이후 TLS 터널로 보호되지 않습니다. 인증 서비스 사용 방법을 선택할 때 그 전송 구간을 별도로 확인하세요.

관련 글