Google Developers Conference参加申し込みで 出題された問題。OAuthの公開鍵を使った3-legged認証ではなく、 共有鍵を使って鍵つきダイジェスト認証をする、著者不在の 2-legged(足)な認証をする。devquizという比較的簡単な問題 なのだけれども、いままで使ったことがないので練習のつもりでやってみた。 自分でGoogle Apps premierを使っていれば、利用したかもしれないが、 そうでもないし。3-legged OAuthを見て、あーめんど、と思って 敬遠していたのもある。
自分の理解のために、手でseed作成とHMAC-SHA1ダイジェスト作成を コーディングしていたが、どうもうまくいかない。しかたなく PythonのコードやPHPのコードを探してみると、いくつかあるが 今回のGoogleのdevquizのようにPOSTで、realmをつけて、Authorization ヘッダで認証する、というコードがない。Pythonのマニュアルの 読み方を調べる直前で、PerlのOAuth::Liteがいい、というのを見て やってみると、関数に引数を与えるだけであっさり認証が完了した。
#!/usr/bin/perl
use 5.0.8;
use strict;
use warnings;
use Data::Dumper;
use OAuth::Lite;
use OAuth::Lite::Consumer;
my $consumer = OAuth::Lite::Consumer->new(
consumer_key => 'YOUR_CONSUMER_KEY',
consumer_secret => 'YOUR_CONSUMER_SECRET',
realm => 'devquiz',
);
my $response = $consumer->request(
method => 'POST',
url => 'http://gdd-2010-quiz-japan.appspot.com/oauth/YOUR_CONSUMER_KEY',
params => {
hello => 'world'
});
if ($response->is_success) {
print Dumper($response->decoded_content);
} else {
warn $response->status_line;
}
PerlのOAuth::Liteは、nonceを自動的に生成し、time()も自動的につけてくれる。 デフォルトはPOSTのAuthorization:ヘッダの、HMAC_SHA1でそろっている。
というわけで、手でコーディングしていたダイジェストの問題は以下のとおりだった。
- seedにはPOSTの送信データであるhello=worldを含めること
- Digest::HMA_SHA1のb64digest()メソッドは、Base64エンコードらしきことを するが、文字列の末尾のパディングをしないため、認証が通らない。
- MIME::Base64のencode_base64()メソッドは、Base64エンコードをするが、 より大きなデータの処理を想定しているため、デフォルトで文字列の 末尾に改行コードを追加する。末尾の改行が不要なときは encode_base64($digest, "")のようにしなければならない。
- realmはoath_なんとかのseedには入れない
mixiの説明は、Googleの説明資料の日本語訳になっていてわかりやすい。 が、PerlのOAuth::Liteを使えば、seedに関連する半分以上の説明は理解しなくてもよい。
















