ラベル cURL の投稿を表示しています。 すべての投稿を表示
ラベル cURL の投稿を表示しています。 すべての投稿を表示

2012年8月27日月曜日

[PHP][cURL] PHPのcURLを使ってGoogleにログインする

YAHOO! 知恵袋に(どなたか本当にお願いします!phpのcurlに関して教えて頂きたいです。)というPHPのcURLを使って、Googleにログインする方法が聞かれていたのでちょっと組んでみた。

実はこういうのは意外と面倒くさくて、
POSTデータでIDとパスワードを飛ばせばいいというものではない。
もちろんそれでログインできる(できてしまう)サイトもあるのだが、
セキュリティポリシーの高いサイトではそうはいかない。
不正なログインを防ぐためにフォーム内にトークンを埋め込み、
かつCookieにもそのトークンを埋め込んでおき、
サブミットされた際にフォームから飛んできたPOSTとCookieを比較しているのだ。
ちなみにGoogleとPixivはこの方式を採用している(2012/08/27現在)。

とりあえず早速ソースを見ていこう。

//URLを指定する
$url='https://accounts.google.com/ServiceLoginAuth';
//POST用のデータを作っておく
$data=array
(
    //ID部分(適宜置き換え)
    'Email'=>'',
    //パスワード部分(適宜置き換え)
    'Passwd'=>'',
    //ログインを維持するかのチェックボックス部分
    //'PersistentCookie'=>'yes',
);
//テンポラリファイルを作成する
$cookie=tempnam(sys_get_temp_dir(),'cookie_');

//cURLを初期化して使用可能にする
$curl=curl_init();
//オプションにURLを設定する
curl_setopt($curl,CURLOPT_URL,$url);
//文字列で結果を返させる
curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
//クッキーを書き込むファイルを指定
curl_setopt($curl,CURLOPT_COOKIEJAR,$cookie);
//URLにアクセスし、結果を文字列として返す
$html=curl_exec($curl);
//cURLのリソースを解放する
curl_close($curl);

//Document初期化
$dom=new DOMDocument();
//html文字列を読み込む(htmlに誤りがある場合エラーが出るので@をつける)
@$dom->loadHTML($html);
//XPath初期化
$xpath=new DOMXPath($dom);
//inputのtypeがhiddenの要素をとってくる
$node=$xpath->query('//input[@type="hidden"]');
foreach($node as $v)
{
    //POST用のデータに追加する
    $data[$v->getAttribute('name')]=$v->getAttribute('value');
}

//cURLを初期化して使用可能にする
$curl=curl_init();
//オプションにURLを設定する
curl_setopt($curl,CURLOPT_URL,$url);
//メソッドをPOSTに設定
curl_setopt ($curl,CURLOPT_POST,true);
//POSTデータ設定
curl_setopt($curl,CURLOPT_POSTFIELDS,$data);
//クッキーを読み込むファイルを指定
curl_setopt($curl,CURLOPT_COOKIEFILE,$cookie);
//Locationをたどる
curl_setopt($curl,CURLOPT_FOLLOWLOCATION,true);
//URLにアクセスし、結果を表示させる
curl_exec($curl);
//cURLのリソースを解放する
curl_close($curl);

//テンポラリファイルを削除
unlink($cookie);

という感じになる。
さて、実際に何をしているか見ていくと

//URLを指定する
$url='https://accounts.google.com/ServiceLoginAuth';
//POST用のデータを作っておく
$data=array
(
    //ID部分(適宜置き換え)
    'Email'=>'',
    //パスワード部分(適宜置き換え)
    'Passwd'=>'',
    //ログインを維持するかのチェックボックス部分
    //'PersistentCookie'=>'yes',
);
//テンポラリファイルを作成する
$cookie=tempnam(sys_get_temp_dir(),'cookie_');

の部分で必要な変数を用意している。
ID部分とパスワード部分は適宜置き換えて欲しい。

//cURLを初期化して使用可能にする
$curl=curl_init();
//オプションにURLを設定する
curl_setopt($curl,CURLOPT_URL,$url);
//文字列で結果を返させる
curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
//クッキーを書き込むファイルを指定
curl_setopt($curl,CURLOPT_COOKIEJAR,$cookie);
//URLにアクセスし、結果を文字列として返す
$html=curl_exec($curl);
//cURLのリソースを解放する
curl_close($curl);

の部分でフォーム内のトークンを分析するためのHTMLを取得する。

//Document初期化
$dom=new DOMDocument();
//html文字列を読み込む(htmlに誤りがある場合エラーが出るので@をつける)
@$dom->loadHTML($html);
//XPath初期化
$xpath=new DOMXPath($dom);
//inputのtypeがhiddenの要素をとってくる
$node=$xpath->query('//input[@type="hidden"]');
foreach($node as $v)
{
    //POST用のデータに追加する
    $data[$v->getAttribute('name')]=$v->getAttribute('value');
}

の部分でHTML解析を実際に行いトークンを取得し、POST用データ配列に入れる。

//cURLを初期化して使用可能にする
$curl=curl_init();
//オプションにURLを設定する
curl_setopt($curl,CURLOPT_URL,$url);
//メソッドをPOSTに設定
curl_setopt ($curl,CURLOPT_POST,true);
//POSTデータ設定
curl_setopt($curl,CURLOPT_POSTFIELDS,$data);
//クッキーを読み込むファイルを指定
curl_setopt($curl,CURLOPT_COOKIEFILE,$cookie);
//Locationをたどる
curl_setopt($curl,CURLOPT_FOLLOWLOCATION,true);
//URLにアクセスし、結果を表示させる
curl_exec($curl);
//cURLのリソースを解放する
curl_close($curl);

の部分で今まで作ったPOSTデータを飛ばしログインしている。

//テンポラリファイルを削除
unlink($cookie);

の部分でcookie保持用に用意したファイルを消しておく。
ただ、実際は放っておけばそのうち勝手に消えてしまうファイルなので、
わざわざ消す必要がないと言えばないのだが・・・

ポイントとなる関数
  • curl_init ・・・ cURL セッションを初期化する
  • curl_setopt ・・・ cURL 転送用オプションを設定する
  • curl_exec ・・・ cURL セッションを実行する
  • curl_close ・・・ cURL セッションを閉じる
  • DOMDocument クラス ・・・ HTML ドキュメントあるいは XML ドキュメント全体を表し、 ドキュメントツリーのルートとなります。
  • DOMXPath クラス ・・・ XPath 1.0 をサポートします。

2012年8月23日木曜日

[PHP][cURL] cURLでリダイレクトをたどるようにする

PHPはサイト解析するためにURLから情報を取得する方法がたくさんある。
その一つにcURLというのがある。
cURLではHTTPステータスコードが300系などで既に移転してしまったサイトなどは
リクエストのヘッダにLocationがあればリダイレクトしてたどっていく機能がある。

//URLを指定する
$url='google.co.jp';

//cURLを初期化して使用可能にする
$curl=curl_init();

//オプションにURLを設定する
curl_setopt($curl,CURLOPT_URL,$url);
//Locationをたどる
curl_setopt($curl,CURLOPT_FOLLOWLOCATION,true);
//最大何回リダイレクトをたどるか
curl_setopt($curl,CURLOPT_MAXREDIRS,10);
//リダイレクトの際にヘッダのRefererを自動的に追加させる
curl_setopt($curl,CURLOPT_AUTOREFERER,true);

//URLにアクセスし、結果を表示させる
curl_exec($curl);

//cURLのリソースを解放する
curl_close($curl);

とすればよい。
意外と自分でリダイレクトをたどり続ける処理を書くのは一手間なので、
こういう細かな機能はありがたい。

ポイントとなる関数
  • curl_init ・・・ cURL セッションを初期化する
  • curl_setopt ・・・ cURL 転送用オプションを設定する
  • curl_exec ・・・ cURL セッションを実行する
  • curl_close ・・・ cURL セッションを閉じる

[PHP][cURL] cURLで結果を文字列として受け取る

PHPは数多くの関数やクラスがあり、URLから結果を取得することができるものもある。
その一つにcURLがある。
cURLはデフォルトでは取得した結果をそのままブラウザやコンソールなどに出力するが、
文字列として受け取りたい場合がある。
その際には

//URLを指定する
$url='www.google.co.jp';

//cURLを初期化して使用可能にする
$curl=curl_init();

//オプションにURLを設定する
curl_setopt($curl,CURLOPT_URL,$url);
//文字列で結果を返させる
curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);

//URLにアクセスし、結果を文字列として返す
$result=curl_exec($curl);

//cURLのリソースを解放する
curl_close($curl);

となる。
この後にDOM解析したり、特定文字列を検知したりとすることになるだろう。

ポイントとなる関数
  • curl_init ・・・ cURL セッションを初期化する
  • curl_setopt ・・・ cURL 転送用オプションを設定する
  • curl_exec ・・・ cURL セッションを実行する
  • curl_close ・・・ cURL セッションを閉じる

[PHP][cURL] cURLでSSL(https)のCA証明書警告の回避や設定

PHPは柔軟な言語で特定のサイトを取得するのに様々な手法がある。
その中でcURLという選択をとる人は多い。
色々と便利なcURLだが、SSL(つまりhttps)で外部のサイトへアクセスした場合

SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

というエラーが出る場合がある。
これはcURLの–with-ca-bundleオプションで指定されたパスか特定パスにCA証明書がないと起こるエラーだ。
もちろん–with-ca-bundleオプションでCA証明書を指定してもいいのだが、
できない環境(レンタルサーバ)などもあるだろう。
これを回避するには

//URLを指定する
$url='https://www.google.co.jp/';

//cURLを初期化して使用可能にする
$curl=curl_init();

//オプションにURLを設定する
curl_setopt($curl,CURLOPT_URL,$url);
//CA証明書の検証をしない
curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,false);

//URLにアクセスし、結果を表示させる
curl_exec($curl);

//cURLのリソースを解放する
curl_close($curl);

としてやればよい。
また、CA証明書を持っているなら

//URLを指定する
$url='https://www.google.co.jp/';
//CA証明書へのパス
$path='./cacert.pem';

//cURLを初期化して使用可能にする
$curl=curl_init();

//オプションにURLを設定する
curl_setopt($curl,CURLOPT_URL,$url);
//CA証明書ファイルを指定
curl_setopt($curl,CURLOPT_CAINFO,$path);

//URLにアクセスし、結果を表示させる
curl_exec($curl);

//cURLのリソースを解放する
curl_close($curl);

としてやればよい。

ポイントとなる関数
  • curl_init ・・・ cURL セッションを初期化する
  • curl_setopt ・・・ cURL 転送用オプションを設定する
  • curl_exec ・・・ cURL セッションを実行する
  • curl_close ・・・ cURL セッションを閉じる

[PHP][cURL] cURLでリクエストヘッダを表示させる

PHPでは特定のサイトにアクセスするのに様々な手法があるが、
その中で便利なものの一つがcURLだ。
そのcURLで相手サイトに想定したパラメータなどが渡ってなくて、
思った通りの結果がとれないときがある。
そのときにはリクエストヘッダを出力してみるといいだろう。

//URLを指定する
$url='www.google.co.jp';

//cURLを初期化して使用可能にする
$curl=curl_init();

//オプションにURLを設定する
curl_setopt($curl,CURLOPT_URL,$url);
//リクエストヘッダ出力設定
curl_setopt($curl,CURLINFO_HEADER_OUT,true);

//URLにアクセスし、結果を表示させる
curl_exec($curl);

//リクエストヘッダ出力
echo curl_getinfo($curl,CURLINFO_HEADER_OUT);

//cURLのリソースを解放する
curl_close($curl);

とすることによってリクエストヘッダを出力させることができる。
ちなみに上記例では

GET / HTTP/1.1
Host: www.google.co.jp
Accept: */*


となっている。
ちなみに余談だが、HTTP1.1ではHostフィールドだけがリクエストヘッダで唯一の必須になっている。

ポイントとなる関数
  • curl_init ・・・ cURL セッションを初期化する
  • curl_setopt ・・・ cURL 転送用オプションを設定する
  • curl_exec ・・・ cURL セッションを実行する
  • curl_getinfo ・・・ 指定した伝送に関する情報を得る
  • curl_close ・・・ cURL セッションを閉じる

[PHP][cURL] cURLでクッキーを送受信する

PHPは特定のURLにアクセスしたりリクエストを送るのが非常に簡単だ。
とりわけcURLを使う方法は結構メジャーである。
cURLには通信のための様々なオプション設定ができるが、
クッキーを扱うためのオプションももちろんある。

相手からクッキーを受け取りたいときは

//URLを指定する
$url='www.google.co.jp';
//テンポラリファイルを作成する
$cookie=tempnam(sys_get_temp_dir(),'cookie_');

//cURLを初期化して使用可能にする
$curl=curl_init();

//オプションにURLを設定する
curl_setopt($curl,CURLOPT_URL,$url);
//クッキーを書き込むファイルを指定
curl_setopt($curl,CURLOPT_COOKIEJAR,$cookie);

//URLにアクセスし、結果を表示させる
curl_exec($curl);

//cURLのリソースを解放する
curl_close($curl);

//クッキーを表示する
echo file_get_contents($cookie);

//テンポラリファイルを削除
unlink($cookie);

となる。
ちなみにクッキーを受け取ったファイルの中身は

# Netscape HTTP Cookie File
# http://www.netscape.com/newsref/std/cookie_spec.html
# This file was generated by libcurl! Edit at your own risk.

ドメイン ドメインクッキーフラグ パス セキュアフラグ 有効期限 名前 値
ドメイン ドメインクッキーフラグ パス セキュアフラグ 有効期限 名前 値
ドメイン ドメインクッキーフラグ パス セキュアフラグ 有効期限 名前 値

となっている。
逆に相手にクッキーを送信したい場合は

//URLを指定する
$url='www.google.co.jp';
//クッキー情報の入ったファイルへのパス
$cookie='./cookie.txt';

//cURLを初期化して使用可能にする
$curl=curl_init();

//オプションにURLを設定する
curl_setopt($curl,CURLOPT_URL,$url);
//クッキーを読み込むファイルを指定
curl_setopt($curl,CURLOPT_COOKIEFILE,$cookie);

//URLにアクセスし、結果を表示させる
curl_exec($curl);

//cURLのリソースを解放する
curl_close($curl);

となる。
ちなみにpixivへの自動ログインを作るためには、
このクッキーの扱いをマスターするのが必須になってる。

ポイントとなる関数
  • curl_init ・・・ cURL セッションを初期化する
  • curl_setopt ・・・ cURL 転送用オプションを設定する
  • curl_exec ・・・ cURL セッションを実行する
  • curl_close ・・・ cURL セッションを閉じる