Настройка curl для работы на https

07.03.2017

Модуль libcurl предназначен для отправки http запросов веб серверам и получения на них ответов. Фактически он делает тоже что и браузер при переходе на страницу какого нибудь сайта. Чтобы воспользоваться предоставляемыми им прелестями, подключим его.

Для начала внимательно читаем документацию. Там сказано, что для полноценной работы модуля требуются дополнительные файлы. Я проверил папку, в которой установлен PHP, в ней присутствуют файлы "ssleay32.dll" и "libeay32.dll", которые требуются, так что всё в порядке. Затем проверил папку расширений "ext", в ней присутствует модуль "php_curl.dll", который собственно и содержит curl. В php.ini раскомментировал этот модуль для загрузки.

extension=php_curl.dll

После перезагрузки службы сервера этот модуль будет работать. Для проверки достаточно написать простой скрипт:

<?php // Инициализация ресурсов curl $ch = curl_init(); // Установка url curl_setopt($ch, CURLOPT_URL, "http://example.com/"); // Возврат порученного ответа в виде строки curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // Выполнение запроса $output = curl_exec($ch); // Проверка результата if( $output ) { echo 'Запрос выполнен'; } else { echo 'Ошибка запроса <br>', curl_error($ch); } // Закрытие соединения и освобождение ресурсов curl_close($ch); ?>

В данном примере был выполнен обычный GET запрос на сайт "example.com". Чтобы выполнить POST запрос, нужно добавить соответствующие опции.

curl_setopt($ch, CURLOPT_POST, 1); $encoded = urlencode(...); curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded);

Здесь $encoded содержит строку параметров вида "urlencode(имя)=urlencode(значение)", соединенных "&". Параметры запроса передаются в точно таком же виде, как и при GET запросе, с разнице лишь в том, что передаются не в URL запроса, а в теле POST запроса. Немного поигравшись с серверами, работающих на обычном http протоколе, попробуем сделать тоже с https протоколом.

// Установка url curl_setopt($ch, CURLOPT_URL, "https://example.com/");

И здесь нас ждет разочарование. Возникает ошибка. Дело в том, что для установки https соединения требуется проверка сертификата сервера. А наш curl пока этого не умеет делать :-(. Можно конечно принудительно отключить проверку, но это не дело, не для того создавался протокол с защитой, чтобы отключать защиту.

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

Проблема заключается в том, что у вашего curl отсутствует сертификат, которым осуществляется проверка сертификата сайта. Вкратце, сертификаты содержат ключи для шифрования, открытый и закрытый, открытый ключ доступен всем, закрытый - никому. Одним ключом зашифровывается, другим расшифровывается. Проверка заключается в том что, обе стороны обмениваются зашифрованной информацией, поскольку у вас нет никаких ключей, то эта процедура становится невозможной. Отсюда и ошибка. (Для тех кто хочет разобраться подробно с ключами, шифрованием, сертификатами и пр. - дорога в гугл или яндекс)

И что же делать? Можно стырить сертификат! Вот на этой страничке (по английски читайте сами) есть ссылка на доступный сертификат. Скачиваем его (он будет в виде обычного текста), затем копируем его в папку с PHP "C:\Program Files\PHP\extras", в php.ini прописываем абсолютный путь к нему:

curl.cainfo="C:\Program Files\PHP\extras\cacert.pem"

Теперь осталось перезапустить службу сервера, и убедиться что curl заработал с протоколом https. Во всяком случае у меня всё заработало. Я пытался на локальном сервере настроить регистрацию в MODx. На форме регистрации установил гугловскую reCaptchav2, и сначала регистрация совершено не работала. После отключения каптчи регистрация заработала, но мне нужна была защита от спама, а переделывать регистрацию под другую капчу не было желания. После недолгого расследования был обнаружен виновник - модуль curl, а спустя некоторое время найдено решение проблемы. И гугловская капча успешно заработала на локальном сервере.