OpenID を理解するために、OpenID Consumerをperlで実装してみることにした。といっても、 Net::OpenID::Consumer モジュールを利用しているわけで、いちから自分で実装しているわけではないです。「モジュールがあるから楽勝」と思っていたら、意外とてこずってしまいました。動作サンプル。ソース。
認証時の流れについては、「ぴろ日記 - OpenID: Specs , OpenID認証サーバ , OpenIDにおける認証って奴」が詳しいです。今回実装しているのは、ぴろ日記さんで「とりあえずわかりやすい」と言われている、「dumb + setup モード」です。
以下、簡単に説明を。
動作サンプルにアクセスすると、以下の部分が実行されます。
sub login { my $self = shift; if($self->query->param('openid.sig')){ my $csr = $self->_create_csr; my $vident = $csr->verified_identity or die $!; return 'You are <strong>' . $vident->url . '</strong> !'; } else { my $template = $self->load_tmpl('login.html'); return $template->output; } }
openid.sig パラメータが渡されていると、Open ID Serverに対して認証情報の正当性を確認しに行きますが、まだ最初のアクセスで認証していませんので、else 以下が実行されて、ログインフォームを表示します。
ログインフォームに、自分のIDとなるURLを入力、サブミットすると以下のコードが実行されます。
sub do_login { my $self = shift; my $csr = $self->_create_csr; my $claimed_identity = $csr->claimed_identity($self->query->param('openid_url')); my $check_url = $claimed_identity->check_url( return_to => 'http://mizzy.org/openid/', trust_root => 'http://mizzy.org/', delayed_return => 1, ); $self->header_type('redirect'); $self->header_props(-url => $check_url); return; } sub _create_csr { my $self = shift; my $csr = Net::OpenID::Consumer->new( args => $self->query, consumer_secret => '012345', ); return $csr; }
ここでは、ぴろ日記さんの説明にある、1), 2)の処理が実行され、OpenID Serverへリダイレクトされます。この処理は、OpenID: Specs の checkid_setup にあたります。
OpenID Server上での認証が完了すると、QUERY_STRINGに様々なパラメータをセットした状態で、http://mizzy.org/openid/ へ戻ってき、最初と同様以下のサブルーチンが実行されます。
sub login { my $self = shift; if($self->query->param('openid.sig')){ my $csr = $self->_create_csr; my $vident = $csr->verified_identity or die $!; return 'You are <strong>' . $vident->url . '</strong> !'; } else { my $template = $self->load_tmpl('login.html'); return $template->output; } }
今度はopenid.sigパラメータ(と他のOpenID関連パラメータ)が QUERY_STRINGにより渡されていますので、 $csr->verified_identity を実行して、ぴろ日記さんの説明4)にあたる、認証情報の正当性確認を OpenID Server に対して行います。この処理は、OpenID: Specs の check_authentication にあたります。
正当性が確認できると、「You are あなたのURL !」 と表示されます。
username.videntity.org と livejournal.com/users/username/ はIDとして正常に動作することが確認できましたが、profile.typekey.com/username/ はなぜか openid.mode=cancel となってしまい、認証できません。videntity.org のログインに profile.typekey.com/username/ を利用しても認証できないので、typekey 側の問題なのかなぁ…