はてな認証API / ためしに作ってみました
はてな認証APIが公開されましたので、ためしてみました。
懸念事項
なおやさんところ経由ではてな認証APIの公開について(開発者さま向け)を読んで感じたこと。
結城さんちのはてな認証APIテスト
追記:2006-04-24 21:09: とりあえず、作ってみました。以下をお試しください(ソースはすぐ下で公開)♪
これは、はてな認証サーバから返された文字列をそのまま表示するだけのアプリです。id:hyukiとid:rubycoさんでうまくいくことを試しました。
追記:2006-04-24 21:49: catfrogさんへ:上の「結城さんちのはてな認証APIテスト」を試してみるとすぐにアプリのイメージは浮かぶと思います。もっとも単純なのは掲示板アプリで、はてなユーザとして認証された人だけは「名前の部分がその人のはてなダイアリーにリンクされている」というようなもの。たとえばはてなダイアリーのコメント欄がまさにそうなってますよね。
追記:2006-04-24 21:59: 一度「結城さんちのはてな認証APIテスト」用に許可すると、はてなのシステムが覚えるみたいですね。もう一度新たな気持ちでやってみたいときには、はてな認証APIのところで許可を取り消す必要があるようです。なるほど。
追記:2006-04-24 22:04: r_iizukaさんへ:URLをクリックしたときには説明用のページにジャンプさせるべきでした。実装次第というよりも、結城が入力するURLを間違えていただけです(^_^; 現在は直してあります。
追記:2006-04-24 22:07: 実装してみて気になった点。認証APIでの「説明文を用意するURL」と「認証のコールバックURL」が無関係でもよいというのはまずいのではないか。というのは、ユーザが「許可を与える」というボタンを押すときに見えているのは説明文のURLだけだから。
はてな認証APIのURLの作り方(make_api_sig.pl)
秘密鍵とapi_keyを入手してからapi_sigを作るには、以下のPerlスクリプト(make_api_sig.pl)が使えます。$secretにあなたの秘密鍵、$api_keyにあなたのapi_keyを入れ、ローカルに動かします。
use strict; use Digest::MD5 qw(md5_hex); my $secret = "0123456789abcdef"; my $api_key = "abcdef0123456789abcdef0123456789"; my $api_sig = md5_hex("${secret}api_key${api_key}"); print "secret = $secret\n"; print "api_key = $api_key\n"; print "api_sig = $api_sig\n"; print "URL = http://auth.hatena.ne.jp/auth?api_key=${api_key}&api_sig=${api_sig}\n";
結城さんちのはてな認証APIテストのソース(test.cgi)
追記:2006-04-24 23:27: CGIのソース(test.cgi)を公開します。$secretはあなたの秘密鍵、$api_keyはあなたのapi_key、$help_urlは説明文のURLです。
#!/usr/bin/perl use strict; use CGI; use CGI::Carp qw(fatalsToBrowser); use Digest::MD5 qw(md5_hex); use LWP::Simple; my $q = new CGI; my $cert = $q->param("cert"); my $secret = "0123456789abcdef"; my $api_key = "abcdef0123456789abcdef0123456789"; my $api_sig = md5_hex("${secret}api_key${api_key}cert${cert}"); my $help_url = "http://www.example.com/about_your_application.html"; unless ($cert) { print "Location: $help_url\n\n"; exit; } my $content = get("http://auth.hatena.ne.jp/api/auth.json/?api_key=${api_key}&cert=${cert}&api_sig=${api_sig}"); print $q->header, $q->start_html('Hatena Auth API Test'), $q->start_pre, $content, $q->end_pre, $q->end_html;
はてな認証APIシーケンス図(概略)
追記:2006-04-25 06:15: シーケンス図を描きました(概略のみ)。
- (1) ユーザAは、サービスXに「利用したい」という。
- たとえばサービスXのどこかのページにアクセスすることを意味します。
- (2) サービスXは、ユーザAに「api_keyとapi_sig1」を渡す。
- (3) ユーザAは、はてなに「id+password+api_key+api_sig1」を渡す。
- 通常はユーザAがブラウザでアクセスすることによって渡します。
- (4) はてなは、ユーザAに「cert」を渡す。
- 実際には(4)と(5)は自動的にリダイレクトされますので、ユーザAは意識しません。
- (5) ユーザAは、サービスXに「cert」を渡す。
- ここでアクセスするのがコールバックURLです。
- サービスXはcertは知り得るが、certからpasswordを逆算することはできません(そのようになっていなければなりません)。
- (6) サービスXは、はてなに「api_key+cert+api_sig2」を渡す。
- (7) はてなは、サービスXに認証結果とアイコン情報などを渡す(OKなら)。
- (8) サービスXは、認証後の画面をユーザAに提示する。
※こうやってみると、改めて一方向ハッシュ関数(メッセージダイジェスト)の重要性がよくわかりますね。
※上記のapi_sig1やapi_sig2の作成では秘密鍵を混ぜ込んでメッセージダイジェスト(MD5)を利用しているので、メッセージ認証コードの一種を作っていることになる。一方向ハッシュ関数(メッセージダイジェスト)やメッセージ認証コードについては『暗号技術入門 ―― 秘密の国のアリス』がわかりやすいですよ、と自著の宣伝:-)。