Net::OpenID::Consumerでsregを試す
ふと思い立ってOpenIDが使えるちょっとしたサービスを作ってみようかなと思っています。
で、その中でsreg*1を使いたかったのでNet::OpenID::Consumerのopenid2 branchで出来るかどうか調べてみました。
その前にsregについて具体的に説明
The request parameters detailed here SHOULD be sent with OpenID Authentication checkid_immediate or checkid_setup requests. This extension works with both versions 1.1 (Recordon, D. and B. Fitzpatrick, “OpenID Authentication 1.1,” .) [OpenIDAuthentication1.1] and 2.0 (Recordon, D., Hoyt, J., Hardt, D., and B. Fitzpatrick, “OpenID Authentication 2.0 - Draft 10,” 2006.) [OpenIDAuthentication2.0] of the OpenID Authentication protocol.
まぁ簡単に要約するとですね。
って事ですね。
で、送るパラメータは、
name | detail | ||
openid.ns.sreg | http://openid.net/extensions/sreg/1.1 | ||
openid.sreg.required | カンマ区切りで欲しいプロフィールの名前 |
とかですね。openid.sreg.optional, openid.sreg.policy_urlもありますが、今回は簡単の為考慮しません。カンマ区切りの値は4. Response Formatに列挙してある値でopenid.sreg.をprefixにしてある値で、このprefixの値は省略することになります。つまり、
openid.sreg.required=nickname,email
とかとか、そういう事になりますね。
そうするとOpenID Providerがsregに対応してて、ユーザーがそのprofileを公開する事に同意した場合は、これらの値がレスポンスと一緒に返って来ます。
つまるところ会員登録とかでの入力補助、補完と言う場面で使うような機能ですね。
説明おしまい。
Net::OpenID::Consumerで試す
まずはコードから。
#!/usr/bin/perl use strict; use warnings; use Cache::File; use LWP::UserAgent; use Net::OpenID::Consumer; ### ここは固定になってるけど実際はユーザーのclaimed_id my $claimed_id = "zigorou.myopenid.com"; my $csr = Net::OpenID::Consumer->new( ua => LWP::UserAgent->new, cache => Cache::File->new( cache_root => '/tmp/openid', default_expires => '6000 sec' ), consumer_secret => 'zigorou', args => {}, required_root => 'http://localhost:3000/', debug => 1, ); if (my $cident = $csr->claimed_identity($claimed_id)) { ### ここがポイント $cident->set_extension_args("http://openid.net/extensions/sreg/1.1", { required => join(",", qw/email nickname/) }); my $check_url = $cident->check_url( return_to => "http://localhost:3000/login/handler", trust_root => "http://localhost:3000/", delayed_return => "checkid_setup", ); ### 実際にはUserAgentに対してこのcheck_urlにリダイレクトさせる print "[check_url]\n"; print $check_url; }
適宜コメント振りました。
ポイントはNet::OpenID::ClaimedIdentifierオブジェクトのset_extension_argsに対して、ソースのような値を入れて行くのがポイントです。
こうする事によってcheck_url、即ちcheckid_setupの時のリクエストURLのパラメータに先ほど説明したようなopenid.ns.sregとか、openid.sreg.requiredがセットされます。実行結果を見てみると、
http://www.myopenid.com/server? openid.ns=http://specs.openid.net/auth/2.0& openid.return_to=http://localhost:3000/login/handler%3Foic.time%3D1206197561-a06a907ab7899fbd2e83&openid.claimed_id=http://zigorou.myopenid.com/& openid.identity=http://zigorou.myopenid.com/& openid.mode=checkid_setup& openid.realm=http://localhost:3000/& openid.assoc_handle=%7BHMAC-SHA1%7D%7B47e51527%7D%7BwyS0XA%3D%3D%7D& openid.ns.e1=http://openid.net/extensions/sreg/1.1& openid.e1.required=email,nickname
となりsregではなくs1みたいになってますね。
ちなみに実行結果は見易さの為に適宜改行しています。
これはNet::OpenID::Consumer側でのcheck_urlメソッドの実装にて、168行目付近から、
# Finally we add in the extension arguments, if any my %ext_url_args = (); my $ext_idx = 1; foreach my $ext_uri (keys %{$self->{extension_args}}) { my $ext_alias; if ($self->protocol_version >= 2) { $ext_alias = 'e'.($ext_idx++); $ext_url_args{'openid.ns.'.$ext_alias} = $ext_uri; } else { # For OpenID 1.1 only the "SREG" extension is allowed, # and it must use the "openid.sreg." prefix. next unless $ext_uri eq "http://openid.net/extensions/sreg/1.1"; $ext_alias = "sreg"; } foreach my $k (keys %{$self->{extension_args}{$ext_uri}}) { $ext_url_args{'openid.'.$ext_alias.'.'.$k} = $self->{extension_args}{$ext_uri}{$k}; } }
となってますが、OpenID Authentication 2.0プロトコルの場合は、aliasを使ってprefixを指定出来るんですね。ちょうどxmlnsみたいですね。
もちろんきちんと何の拡張なのかnamespaceを表すURIをaliasに対して明記する必要がありますが。