Perl使ってFlickrAPIでの認証法がやっとわかった

いやー難しかった.何が難しいって,CPANのFlickr::APIの使い方を理解するまでがw Flickrの仕様はドキュメント読めば大体わかるのだが,せっかくモジュールあるので 使おうと思ったら,使い方がWEBで見つからなくて困った.とりあえず動作するフローが 分かったので記録してきます.基本的に下のドキュメントにしたがってやるだけ.

API keyの取得

とりあえずFlickrにログインしてアクセスし,API keyを作っておきます. サービスの名前とか聞かれますが空でも大丈夫でした.大事なのは サービスのタイプで,WEBサーバ立ててごにょごにょしないのであれば, Desktopタイプを選択しておきましょう.WebかDesktopかで認証法が異なります.

Flickr Services できあがるとこんな感じで2つのキーができます.「key」というのはこの サービスを示すキーですが,「Secret」というのはパラメータなどをFlickrに 送る際に送る前にハッシュの署名を作るためのものです.いわば,秘密鍵と公開鍵 みたいなもんですね.

まずはFrobの取得から

ここからはユーザサイドの挙動を作ることになります.ユーザ認証するためには まずFrobというものを取得する必要があります.これはおそらく認証を要求された ユーザの情報を含むもので,flickr.auth.getFrobというAPIを叩くと返ってきます. で,これを使ってユーザに認証してもらってからトークンの取得をすれば良いようです.

で,flickr.auth.getFrobの叩き方ですが,methodとしてflickr.auth.getFrob, api_keyとして先ほどのキーを与えるので,それらとSecret keyをくっつけた 文字列のハッシュを取得して,これをapi_sigとします.これもくっつけて APIを叩くことで,向こうでも同様にハッシュをとって正しいクエリかどうか 判断します.公開鍵認証と同じ感じですね.で,この手順をさくっとやってくれるのが Flickr::APIだということに気づくのに時間がかかったw

使い方は実は至って簡単で,以下の様にするだけ.

my $key = '****************************************';
my $sec = '********************';
my $api = new Flickr::API({'key' => $key, 'secret' => $sec});
my $response = $api->execute_method('flickr.auth.getFrob');

めっちゃ簡単じゃんw なのにFlickr::APIのソースとドキュメントを見比べまくった おれって一体・・・.とにかくこれで$responseの中にfrobが入っています.

しかし,これにアクセスする正しい方法がわからん・・・.とりあえず ハッシュと配列の組み合わせなのでData::Dumperしてみてそれをみながら 苦肉の策.たぶん間違ってる><

my $frob = $response->{tree}->{children}[1]->{children}[0]->{content};

ま,うごくのでよしとするw

認証してもらってからトークンの取得

続いて,先ほど取得したfrobを使って,ユーザの認証用のURLを作ります. これもFlickr::APIを使えば簡単.(まぁ使わなくても簡単だけどw)

print $api->request_auth_url('write', $frob) . "\n";

writeの部分は自分が欲しいレベルを設定します.delete>write>readの順で 使えるものが少なくなります.今回僕はUploadとかもしたいのでwriteにしています.

そうしたら,これでコンソールに表示されるURLにFlickrにログインしたブラウザから アクセスします.すると,おなじみの認証画面になりますので「OK」をクリック.

この状態で,flickr.auth.getTokenというAPIを叩いてトークンを取得します. これさえ獲得すれば,もう次からこんなめんどくさいことは必要なくなります. 取得の方法は,methodにflickr.auth.getToken,api_keyにキー,frobに取得している frobをセットして叩けばOK.もちろんFlickr::APIにまかせてしまいましょう.

$response = $api->execute_method('flickr.auth.getToken',{'frob' => $frob});

これで,先ほどと同様に$responseの中に見事トークンが入っているはずです. frobと同じく,無理矢理とりだしますw

my $token = $response->{tree}->{children}[1]->{children}[1]->{children}[0]->{content};

以降は,frobとかは必要なくなり,keyとtokenをAPIにくっつけて送れば OKです.ただし,多分secretによるハッシュもくっつけて送る必要はあると思います.

というわけでFlickr::Uploadを使って試しに写真を上げてみる

まとめとしてFlickr::APIを継承してるFlickr::Uploadを使って写真を上げるスクリプトを のせておきます.お疲れさまでした>< frobやtokenの取り出し方教えて下さい! XML::Parse::Liteってやつらしいです.

use Flickr::Upload;

my $key = '****************************************';
my $sec = '********************';
my $api = new Flickr::Upload({'key' => $key, 'secret' => $sec});

my $response = $api->execute_method('flickr.auth.getFrob');

my $frob = $response->{tree}->{children}[1]->{children}[0]->{content};
print $frob . "\n";

print $api->request_auth_url('write', $frob) . "\n";
my $line = <stdin>; #URLにアクセスして認証したらEnter入力w

$response = $api->execute_method('flickr.auth.getToken',{
    'frob' => $frob});

my $token = $response->{tree}->{children}[1]->{children}[1]->{children}[0]->{content};
print $token . "\n";

$api->upload(
    'photo' => '/home/user/image.jpg',
    'auth_token' => $token,
    'is_public' => 0,
    'is_friend' => 0,
    'is_family' => 0,
    );