SSLで保護されたWebサイトにcurlでログインしようとしましたが、どういうわけか正しくログインできません。
最初のcurl接続は、ログインフォームを取得します。最初のSSLの問題は現在解決されています。認証に使用されるフィールドとすべての非表示フィールドが識別され、次のPOSTに使用されます。Cookieファイルが定義され、そこから読み取るjarも定義されます。Cookieファイルはアクセス可能であり、ログインを試みるたびに更新されます。セッションCookieはcurlによって正常に設定されます。HTTPHEADERが削除され、リクエストが100Continueウォールにヒットするのを防ぎます。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ハンドルを使用してPOSTします。
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $options);
$data = curl_exec($ch);
$error=curl_error($ch);
しかし、返されるのは、CURLOPT_COOKIESESSION設定に応じて、同じフォームと同じセッションCookieまたは新しいCookieだけです。
手動でログインすると、LtpaTokenとLtpaToken2の2つのCookieが設定されていることに気付きましたが、スクリプトによって出力されたリクエストヘッダーにそれらが表示されることはありません。フォームを手動で送信すると、Javascriptを使用しなくても機能します。したがって、フォームデータを送信する前に内部でフォームデータを変更するJSマジックはあり得ません。明らかに、私はここで何かが欠けています。さらに調べることができるアイデアはありますか?
解決済み:最後に、この問題はPOSTのエンコーディングの問題が原因でした。最初に、POSTデータはhttp_build_query()を使用して配列から作成されました。これで、POSTデータは単純に連結され、キーと値の両方が別々にurlencodedされます。
$options.=urlencode($fieldName).'='.urlencode($element->getAttribute('value'));