【PHP】コマンドラインでサイトへのログイン処理を実装する方法

はじめに

今回やりたかったことは、APIなどが公開されていないサービスでのログイン処理をバッチなどで行って処理するということ。

イメージとしては
・会員制サイトへの自動書き込み
・オークションサイトへの自動出品

とかでしょうか。大手のサイトだったらAPIが公開されていることが多いのでAPI叩けばいいだけなんですけど、小規模なサイトだとそうもいかず

実装手順

ブラウザでやってることなのでそれをそのままかけば簡単にできました。

手順としては、
1. サイトへアクセス(クッキーが発行されるのでそれを取得)

2. ログイン画面へID(またはEmailなど)とパスワードを送信(その際に1.で取得したクッキーも一緒に送信)

3. ログイン後にやりたい処理を実行(URLを調べてリクエストする)

実装方法

// ログイン情報
$user = "user";
$password = "pass";

// 1. ログイン画面等へアクセス(クッキーを発行させる)
$url = "http://example.com/login"
$response = file_get_contents($url)

// クッキーを取得
// ★ここがポイント file_get_contents後に$http_response_headerにレスポンスヘッダが格納されているのでここからクッキー情報を取得
$cookies = array();
foreach ($http_response_header as $v) {
    list($key, $value) = explode(":", $v);
    if ($key == "Set-Cookie") {
        $cookies[] = $value;
    }
}

// CookieからSessionIdを取得                            
$session_id = "";
foreach ($cookies as $v) {
    if (preg_match("/SESSIONID=(.+); /", $v)) {
        $session_id = $v;
    }
}

// 2.  ログイン処理
$url = "http://example.com/login"
$method = "POST";

$request = array(
    "user" => $user,
    "password" => $password,
);

$query = http_build_query($request, "", "&");

$header = array(
    "Content-Type: application/x-www-form-urlencoded",
    "Content-Length: " . strlen($query),
    "Cookie: " . "Cookie: " . $session_id, // ★セッション管理ではセッションIDをクッキーにいれることがほとんどなので一緒に送信
    "User-Agent: " . "hogehoge", // UserAgentで弾いてるサイトもあるので必要なら適当にセット
);

$context = array(
    "http" => array(
        "method" => $method,
        "header" => implode("\r\n", $header),
        "content" => $query,
    )
);

$response = file_get_contents($url, false, stream_context_create($context));

// 3. ログイン後にやりたい処理を実行
$url = "http://example.com/login"
$request = array(
);
$query = http_build_query($request, "", "&");

// header                                                                                                                                                                                                      
$header = array(
    "Cookie: " . "Cookie: " . $session_id,
    ・・・
);

$context = array(
   "http" => array(
        "method" => $method,
        "header" => implode("\r\n", $header),
        "content" => $query,
    )
);

$response = file_get_contents($url, false, stream_context_create($context));

サイト運営者からすると、あんまりやってほしくないこともあるかもしれませんが、とりあえずこんなかんじでブラウザと同じ挙動を実施できます。

まぁ、大手のサイトとかだと他にもセキュリティ上いろいろチェックしてる可能性はあるのでうまくいかないこともあるかもしれませんが、、、

さいごに

サイトごとにURLやパラメータをHTMLから調べる必要があるので手間な作業ではあるのですが、できないことはなさそうですね
とういうお話でした

以上です