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,
    );