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 側の問題なのかなぁ…