【WordPress】curl で自動ログインしてバッチ処理する方法

June 9, 2015

WordPress では、get_posts() などで公開されていない下書きや予約投稿の記事を取得する場合適切なアカウントでログインしている必要があります。ローカル環境では成功するバッチ処理が本番サイトでは失敗するので調べたところ判明。自動ログインしてバッチ処理を定期実行する実装をメモしておきます。

How to Automatic Log-in to WordPress Using cURL

本稿で扱うバッチ処理の概要は以下の通りです。

  • バッチ処理は page-batch.php として用意する
    (こうすることで スラッグに batch を設定した固定ページを公開し そのページにアクセスすると起動します)
  • functions.php にて自動ログイン用のダミー URL(http://example.com/ZCuMXwXnH3DJpQTJ/)をトラップする
  • 自動ログイン用 URL へのアクセスは wp_signon() 関数で管理者としてログインした後 wp_redirect() 関数で /batch/ ページにリダイレクトする
  • cron に curl を設定し自動ログイン用 URL にアクセスすると自動ログインしてバッチ処理が実行される

自動ログインとリダイレクト

functions.php に以下のコードを追加しました。

ユーザー エージェントをパスワード代わりに使っています。ベーシック認証くらいのセキュリティにはなると思いますが、ご利用は自己責任でお願い致します(もちろん文字列は変更してくださいね!)

function auto_signon_for_batch() {
	wp_signon( array( 'user_login' => 'administrator', 'user_password' => '********', 'remember' => false ), false );
	wp_redirect( 'http://' . $_SERVER['HTTP_HOST'] . '/batch/', 301 );
	exit;
}
if ( '/ZCuMXwXnH3DJpQTJ/' == $_SERVER['REQUEST_URI'] && 'e2NTu9NyKtMqJUSZ' == $_SERVER['HTTP_USER_AGENT'] ) {
	add_action( 'after_setup_theme', 'auto_signon_for_batch' );
}

参考サイト

curl コマンド

curl -c cookies.txt -b cookies.txt -A e2NTu9NyKtMqJUSZ -L http://example.com/ZCuMXwXnH3DJpQTJ/

-c オプション

クッキーを書き込むファイルを指定する。

-b オプション

サーバにクッキーを送信する。

-A オプション

ユーザー エージェントを指定する。

-L オプション

リダイレクトに対応する。

詳しくは以下のページをご参照ください。

バッチ処理(page-batch.php)

必要に応じて、処理の最初に適切なアカウントでログインされているかチェックした方が良いと思います。

...
if ( is_user_logged_in() ) {
...
}

または

...
if ( current_user_can( 'Administrator' ) ) {
...
}

補足

「下書きや予約投稿の記事を取得する場合は権限が必要」という衝撃の事実は Codex(英語版)で記述を見つけました。

Status Parameters

Show posts associated with certain status.

post_status (string / array) – use post status. Retrieves posts by Post Status. Default value is ‘publish’, but if the user is logged in, ‘private’ is added. And if the query is run in an admin context (administration area or AJAX call), protected statuses are added too. By default protected statuses are ‘future’, ‘draft’ and ‘pending’.

(意訳)
post_status はデフォルトだと公開(publish)されている記事しか取得できないよ。(中略)でも管理者エリアや AJAX コールならプロテクト ステータスの記事も取得できるよ。デフォルトでプロテクトされているのは予約投稿、下書き、レビュー待ちの 3つだよ。

これ、よくよく考えてみると衝撃でも何でもなくて当たり前でした。WP Query はサイトのメインクエリとして使われているので、プロテクトされていなかったら、URL で記事IDを直接指定すると記事が表示されてしまいます。バッチ処理で記事を取得する際は WP Query を使わず DB に直接クエリを投げるというのが正しい選択かも知れません。

コメントを残す

メールアドレスが公開されることはありません。