No.2410 そろそろOAuth対応しないとヤベーんじゃねーのと思ってるPHPerに贈るコピペ用コード
そろそろOAuth対応しないとヤベーんじゃねーのと思ってるPHPerに贈るコピペ用コード
ツイッターAPIですが6月30日からBASIC認証がNGになるということで、なんか適当にbotとか作ったんだけどそろそろ対応しないといけないんじゃねーの?と思ってる方もいらっしゃるのではないかと思います。そんなお困りのあなたに今日はコピペ用コードをご用意しました。
以下、BASIC認証をOAuth認証に変更するための大まかな順序です。
では具体的な方法について説明しますが、今回説明するのはbot等のユーザー固定のツイッターアプリの認証方法をOAuthに変える方法です。OAuth認証を使って不特定多数のユーザーからウェブサービスを利用できるようにする方法ではありませんのでご注意ください。
OAuthライブラリをダウンロードする
一からコーディングしてもいいのですが全部説明するのも面倒なので、その辺に転がってるライブラリを利用させて頂くことにします。探せばPHPのOAuthライブラリも色々あると思いますが、今回はツイッター本家のページからリンクされているTwitterOAuthを利用することにします。(以下の例ではこのライブラリを使用しjsonでツイッターAPIを呼び出していますが、PHP-5.2.10未満のjsonモジュールにはバグがあるため、PHP-5.2.10以降が必要です。この辺については後述します。)
http://github.com/abraham/twitteroauthにアクセスしてアーカイブをダウンロードしてもいいのですが(そうしたい人はどうぞ)、必要なのはOAuth.phpとtwitteroauth.phpの二つだけですので、http://github.com/abraham/twitteroauth/tree/master/twitteroauth/から個別にファイルをダウンロードした方が早いと思います。
とりあえずダウンロードしたら適当なフォルダに保存しておいてください。使い方は後で説明します。
OAuthアプリケーション登録する
ライブラリをダウンロードしたらOAuthアプリケーション登録をします。順番的にはこちらを先にしても構いません。
アプリケーション登録はhttp://dev.twitter.com/apps/newから行います。ページにアクセスすると以下の登録フォームが表示されます。
各項目には以下の内容を入力してください。
- アプリケーション名: OAuthアプリケーションの名称。OAuth経由でつぶやいたとき、ツイッターのタイムラインにこのアプリ名が表示されます。
- アプリケーションの説明: とりあえず適当に。
- アプリケーションのウェブサイトURL: ウェブサイトを持ってる人は自分のサイトのURLをセットしとけば良いです。ツイッターのタイムラインのアプリ名をクリックするとこのURLが開きます。ウェブサイト持ってない人は、自分のtwitterアカウントページとか、上の例みたいにexample.comとかをセットしとけば良いと思います。
- お知らせ機能: とりあえず空でいいです。
- あなたの招待状: 今回はBASIC認証からOAuthへの移行のみを例にしていますので、送信にします。不特定多数から使用可能なウェブアプリを作成する場合はブラウザアプリケーションにする必要があります。
- Default Access type: アプリからツイッターに投稿する場合はRead & Write、しない場合はRead-onlyを指定します。
各項目を入力したら「アプリケーションを登録する」ボタンを押してください。エラーが無ければアプリケーションのページに遷移します。
アプリケーションのページに遷移したら後で必要になる項目を控えておいてください。まずアプリケーションのページのOAuth 1.0a Settingsから、Consumer keyとConsumer secret(以下のモザイクをかけた部分)をメモっておきます。
次に、アプリケーションのページのサイドバーのMy Access Tokenをクリックし、oauth_tokenとoauth_token_secret(以下のモザイクをかけた部分)をメモっておきます。
oauth_token_secretとかは人が読める形で保存するなと書いてますが、(繰り返し言いますが非公開前提ですので)華麗にスルーします。
コードを直す
準備が終わりましたので、プログラムの方をいじくります。
例として、home_timelineを読み込む処理を想定します。PHPのcURLモジュールを使用してAPIを呼び出し、jsonモジュールでPHPのオブジェクトに変換しています。
<?php function home_timeline($username, $password) { $ch = curl_init('http://api.twitter.com/1/statuses/home_timeline.json'); curl_setopt($ch, CURLOPT_USERPWD, "{$username}:{$password}"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $ctx = curl_exec($ch); if ($ctx === false) { curl_close($ch); return false; } $info = curl_getinfo($ch); curl_close($ch); if ($info['http_code'] != 200) { return false; } return json_decode($ctx); }
これをBASIC認証をOAuth認証に変えます。ダウンロードしたtwitteroauth.phpとOAuth.phpを同じディレクトリ(もしくは適当なPATH)に配置し、以下のようにコードを書き換え認証をOAuthに変更します。
<?php require_once 'twitteroauth.php'; $CONSUMER_KEY = 'CONSUMER_KEY'; $CONSUMER_SECRET = 'CONSUMER_SECRET'; function oauth_home_timeline($oauth_token, $oauth_token_secret) { global $CONSUMER_KEY, $CONSUMER_SECRET; $t = new TwitterOAuth($CONSUMER_KEY, $CONSUMER_SECRET, $oauth_token, $oauth_token_secret); $result = $t->get('statuses/home_timeline'); if ($t->http_code != 200) { return false; } if (isset($result->error)) { return false; } return $result; }
$CONSUMER_KEYと$CONSUMER_SECRETにはアプリケーション登録時にメモったConsumer keyとConsumer secretをセットしてください。関数の引数の$oauth_tokenと$oauth_token_secretにはMy Access Tokenのoauth_tokenとoauth_token_secretをセットします。この辺の作りについてはあくまでも例ですのでお好きなように。require_onceと、new TwitterOAuthからreturn $resultあたりをコピペして、元のコードに合わせて適当に改造してください。
TwitterOAuthを使用する場合、API呼び出し時のエントリポイントとなるURL(http://api.twitter.com/1/statuses/home_timeline.json)は、TwitterOAuthが適当に変換してくれます。上の例ではその挙動を利用してTwitterOAuth::getの引数に'statuses/home_timeline'を渡していますが、完全なURLを指定してもちゃんと動きます。
次はpostする例です。呼び出すAPIがupdate.jsonになり、POSTメソッドでHTTPリクエストを発行していること以外は上の例と同じです。
<?php function post($username, $password, $status) { $ch = curl_init('http://api.twitter.com/1/statuses/update.json'); curl_setopt($ch, CURLOPT_USERPWD, "{$username}:{$password}"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, 'status=' . rawurlencode($status)); $ctx = curl_exec($ch); if ($ctx === false) { curl_close($ch); return false; } $info = curl_getinfo($ch); curl_close($ch); if ($info['http_code'] != 200) { return false; } return json_decode($ctx); }
これも認証をOAuthに変更します。API呼び出しに使用するメソッドがTwitterOAuth::getでは無くTwitterOAuth::postとなっている点以外については、基本的に上のhome_timelineの例と同じです。
<?php require_once 'twitteroauth.php'; $CONSUMER_KEY = 'CONSUMER_KEY'; $CONSUMER_SECRET = 'CONSUMER_SECRET'; function oauth_post($oauth_token, $oauth_token_secret, $status) { global $CONSUMER_KEY, $CONSUMER_SECRET; $t = new TwitterOAuth($CONSUMER_KEY, $CONSUMER_SECRET, $oauth_token, $oauth_token_secret); $result = $t->post('statuses/update', array('status' => $status)); if ($t->http_code != 200) { return false; } if (isset($result->error)) { return false; } return $result; }
$status引数が投稿するツイートです。($statusにはUTF-8文字列を渡してください。)
実際に投稿するとhttp://twitter.com/xmalloc1/status/13345684719のようになります。通常「webから」等になっている使用クライアント名がアプリケーション登録した際のアプリケーション名となっており、リンク先も登録時のアプリケーションのウェブサイトURLとなっているのが分かります。
補遺 PHP-5.2.10未満の場合
上述した通りPHP-5.2.10未満のjsonモジュールにはバグがあり、PHPのint(マシン依存、通常32bit)を越える数値を扱うことができません。