素のphp5.4でOAuthする(tumblr編)
問題
tumblrにアプリを登録して、APIで投稿できるところまでやってみて!
解答例
OAuthの仕様にはいろんなケースを考慮して細かいところまで書かれているが、用途が限定されていれば、パラメータの並び替えならksort()関数でよいとか、最初から並び替えて書いておけばいいじゃないかとか、話が簡単な部分は結構あると思う。
php5.4だとパラメータのエンコードも標準関数でできるようになっている。
以下、手順。
1、アプリの登録
アカウント作成は済んでいるものとして、アプリの登録はこちら。
http://www.tumblr.com/oauth/apps
2、Consumer Key と Consumer Secret を取得する
OAuth Consumer Key と Secret Key は、1の登録後の画面に表示されている。
Secret Key は 「Show secret key」をクリックすると表示される。
3、Request Token と Secret を取得する
所定のパラメータを作ったり、署名の計算などが必要となる。
request_tokenはパラメータを全部GETで送っても大丈夫なこともあるようだが、仕様の例にあるように、Authorizationヘッダを使って、POSTする方を書いておく。
<?php //OAuthの Consumer Key and Secret $consumer_key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; $consumer_secret = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'; //Request Token and Secret 取得先URL $url = 'http://www.tumblr.com/oauth/request_token'; //POST or GET $method = 'POST'; //パラメータ(oauth_*のパラメータのみ、他のパラメータは無し) $parameters = array(); $oauth_parameters = array( 'oauth_consumer_key' => $consumer_key, 'oauth_nonce' => microtime(), 'oauth_signature_method' => 'HMAC-SHA1', 'oauth_timestamp' => time(), 'oauth_version' => '1.0', ); //署名を作る(署名の計算に使うパラメータは上のoauth_*のみなので、上のアルファベット順のままで並び替え不要) $base_string = implode('&', array( rawurlencode($method), rawurlencode($url), rawurlencode(http_build_query($oauth_parameters, '', '&', PHP_QUERY_RFC3986)) )); $key = implode('&', array(rawurlencode($consumer_secret), rawurlencode($oauth_token_secret))); $oauth_parameters['oauth_signature'] = base64_encode(hash_hmac('sha1', $base_string, $key, true)); //APIにリクエスト送信 $options = array( 'http'=>array( 'method' => $method, 'header' => array( 'Authorization: OAuth ' . http_build_query($oauth_parameters, '', ',', PHP_QUERY_RFC3986), ), 'content' => http_build_query($parameters) ) ); $result = file_get_contents($url, false, stream_context_create($options)); //結果を確認してみる(Request Token and Secret が返ってくる) var_dump($result);
以下のようなレスポンスが返ってくる(Request Token and Secret)。
string(162) "oauth_token=cccccccccccccccccccccccccccccccccccccccccccccccccc&oauth_token_secret=dddddddddddddddddddddddddddddddddddddddddddddddddd&oauth_callback_confirmed=true"
4、ユーザーにアプリの許可をもらう
ログインしているユーザーに、tumblrの承認画面でアプリを許可してもらう。
Authorize URL に、Request Tokenをパラメータに追加したURLに、ブラウザでアクセスする。
3のRequest Tokenなら、以下のURLになる。
http://www.tumblr.com/oauth/authorize?oauth_token=cccccccccccccccccccccccccccccccccccccccccccccccccc
承認画面が表示されるので、許可する(5へ)。
twitterだと、自分で自分のアプリを承認する場合は、開発者用画面でできてしまうのだが、tumblrにはないようだ。がんばろう。
5、許可されたことを取得する(oauth_verifier または PIN)
4でアプリが許可されると、oauth_tokenとoauth_verifierを引数に付けて、callback URLにリダイレクトされてくる。
特に指定しなければ、tumblrのアプリの設定画面で設定したcallback URLにリダイレクトされる。
一般的なWebサービスなら、サーバー側でこのoauth_tokenとoauth_verifierを取得して次の処理(6)をおこなう。自分で自分のアプリの承認をしたいだけの場合は、ブラウザのアドレスバーのURLからコピー&貼り付けして次の処理すればよい。
tumblrで許可されて、リダイレクト後のアドレス欄から
https://www.softel.co.jp/example/?oauth_token=cccccccccccccccccccccccccccccccccccccccccccccccccc&oauth_verifier=eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
6、Access Token と Secretを取得する
oauth_verifierが取得できたらもうすこし。
Access Token and Secretを取得するためのURLに、Request Token and Secret と oauth_verifierを送る。
これもAuthorizationヘッダでやり取りできる。パラメータは全部ヘッダで送れば、他にGETやPOSTのパラメータはない。仕様の例に沿ってPOSTで送ってみる。
<?php //OAuthの Consumer Key and Secret, Request Token and Secret, oauth_verifier $consumer_key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; $consumer_secret = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'; $oauth_token='cccccccccccccccccccccccccccccccccccccccccccccccccc'; $oauth_token_secret='dddddddddddddddddddddddddddddddddddddddddddddddddd'; $oauth_verifier = 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'; //Access Token and Secret 取得用URL $url = 'http://www.tumblr.com/oauth/access_token'; //POST or GET $method = 'POST'; //パラメータ $parameters = array(); $oauth_parameters = array( 'oauth_consumer_key' => $consumer_key, 'oauth_nonce' => microtime(), 'oauth_signature_method' => 'HMAC-SHA1', 'oauth_timestamp' => time(), 'oauth_token' => $oauth_token, 'oauth_verifier' => $oauth_verifier, 'oauth_version' => '1.0', ); //署名を作る(パラメータは上のoauth_*のみなので、上に書いたアルファベット順のままで並び替え不要) $base_string = implode('&', array( rawurlencode($method), rawurlencode($url), rawurlencode(http_build_query($oauth_parameters, '', '&', PHP_QUERY_RFC3986)) )); $key = implode('&', array(rawurlencode($consumer_secret), rawurlencode($oauth_token_secret))); $oauth_parameters['oauth_signature'] = base64_encode(hash_hmac('sha1', $base_string, $key, true)); //APIにリクエスト送信 $options = array( 'http'=>array( 'method' => $method, 'header' => array( 'Authorization: OAuth ' . http_build_query($oauth_parameters, '', ',', PHP_QUERY_RFC3986), ), 'content' => http_build_query($parameters) ) ); $result = file_get_contents($url, false, stream_context_create($options)); //結果を確認してみる(Access Token and Secret が返ってくる) var_dump($result);
結果例
string(132) "oauth_token=ffffffffffffffffffffffffffffffffffffffffffffffffff&oauth_token_secret=gggggggggggggggggggggggggggggggggggggggggggggggggg"
7、投稿する
Access Token and Secretが取得できたら、ようやくAPIが使える。試しに投稿してみる。
//OAuthのいつもの $base_hostname = 'softel.tumblr.com'; $consumer_key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; $consumer_secret = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'; $oauth_token = 'ffffffffffffffffffffffffffffffffffffffffffffffffff'; $oauth_token_secret = 'gggggggggggggggggggggggggggggggggggggggggggggggggg'; //どの tumblr API $url = 'http://api.tumblr.com/v2/blog/' . $base_hostname . '/post'; //POST or GET $method = 'POST'; //パラメータ $parameters = array( 'type' => 'link', 'title' => 'タイトルタイトルタイトル', 'url' => 'https://www.softel.co.jp/blogs/tech/', 'description' => '概要概要概要概要概要概要', ); $oauth_parameters = array( 'oauth_consumer_key' => $consumer_key, 'oauth_nonce' => microtime(), 'oauth_signature_method' => 'HMAC-SHA1', 'oauth_timestamp' => time(), 'oauth_token' => $oauth_token, 'oauth_version' => '1.0', ); //署名を作る //署名の計算にはoauth_*とAPIのパラメータを含めて全部使う //キーと値でソートする仕様なのだが、キーが重複したり英数字以外が混じったりしないのでksort関数で十分 $a = array_merge($oauth_parameters, $parameters); ksort($a); $base_string = implode('&', array( rawurlencode($method), rawurlencode($url), rawurlencode(http_build_query($a, '', '&', PHP_QUERY_RFC3986)) )); $key = implode('&', array(rawurlencode($consumer_secret), rawurlencode($oauth_token_secret))); $oauth_parameters['oauth_signature'] = base64_encode(hash_hmac('sha1', $base_string, $key, true)); //APIにリクエスト送信 $options = array( 'http'=>array( 'method' => $method, 'header' => array( 'Authorization: OAuth ' . http_build_query($oauth_parameters, '', ',', PHP_QUERY_RFC3986), ), 'content' => http_build_query($parameters) ) ); $result = file_get_contents($url, false, stream_context_create($options)); //結果を確認してみる var_dump($result);
結果例
"{"meta":{"status":201,"msg":"Created"},"response":{"id":12345678901}}"
以上、アクセストークン取得と、APIでの投稿テストまで。
hal 2013年7月23日 00:47
はじめまして。
Google App Engine for Javaでtumblrに投稿する方法を探していて、
こちらのページに辿り着きました。
tumblr公式のライブラリを使用してもうまくいかず、
APIの情報もほとんど見当たらずに困り果てていたのですが、
こちらのページを参考にJavaの処理を記述することで、
ようやく投稿することができました。
とても貴重な情報をありがとうございました。
yoshimura 2013年7月23日 11:14
お役に立てて何よりです♪コメントありがとうございます。
k 2013年10月21日 13:23
3、Request Token と Secret を取得する
の26行目は$oauth_token_secretじゃなくて$consumer_secretかな・・・?