SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 採用情報 ...
技術者募集中

素のphp5.4でOAuthする(tumblr編)

問題

tumblrにアプリを登録して、APIで投稿できるところまでやってみて!

tumblr


解答例

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へ)。

tumblrのアプリの承認画面

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}}"

tumblr投稿後


以上、アクセストークン取得と、APIでの投稿テストまで。


参考

API | tumblr

RFC 5849

関連するメモ

コメント(3)

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かな・・・?