Я пытаюсь войти с помощью curl на защищенный SSL-сайт, но почему-то у меня это не получается.
Первое соединение curl извлекает форму входа. Проблема с SSL в начале решена. Поля, используемые для аутентификации, и все скрытые поля идентифицируются и используются для следующего POST. Файл cookie определен, а также банку для чтения. Файл cookie доступен и обновляется при каждой попытке входа в систему. Сеансовый файл cookie успешно установлен curl. HTTPHEADER удален, чтобы запрос не попал в стену 100 Continue. Curl настроен на отслеживание и отправку реферера. Однако я до сих пор не могу найти, где скрипт зависает. Ни Curl, ни PHP не выдают никаких сообщений об ошибках или предупреждений.
Вот сокращенный скрипт:
$ch = curl_init();
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); // remove Expect header to avoid 100 Continue situations
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla [abbreviated]');
curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__).'/cacert.pem');
curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__).'/cookie.hq.txt'); // write cookies
curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__).'/cookie.hq.txt'); // read cookies
curl_setopt($ch, CURLOPT_COOKIESESSION, 1);
curl_setopt($ch, CURLOPT_URL, 'https://the_url.jsp');
$data = curl_exec($ch);
$error= curl_error($ch);
if(!empty($error))
echo '<p>'.$error.'</p>';
else
echo '<p>ok</p>';
Теперь скрипт читает форму, заполняет учетные данные и отправляет их обратно, используя тот же дескриптор curl_init:
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $options);
$data = curl_exec($ch);
$error=curl_error($ch);
Но все, что я получаю, это снова та же форма и тот же файл cookie сеанса или новый, в зависимости от настройки CURLOPT_COOKIESESSION.
Когда я вхожу в систему вручную, я замечаю, что установлены еще два файла cookie: LtpaToken и LtpaToken2, но я никогда не вижу их в заголовках запросов, распечатываемых сценарием. Отправка формы вручную работает даже без активированного Javascript. Таким образом, не может быть какой-то магии JS, изменяющей данные формы под капотом перед ее отправкой. Очевидно, я что-то здесь упускаю. Любые идеи, где я могу смотреть дальше?
Решено: наконец, проблема возникла из-за проблемы с кодировкой в POST. Первоначально данные POST были созданы из массива с помощью http_build_query(). Теперь данные POST просто объединяются, а ключи и значения кодируются отдельно:
$options.=urlencode($fieldName).'='.urlencode($element->getAttribute('value'));