Rails で OpenID を使う (OpenID::SuccessRequest#redirect_url を読もう編)
引き続き、ユーザに OpenID のアカウント (URL) を入力してもらい、OpenIDの認証サーバに誘導するところの処理について。
request = consumer.begin(openid_url) url = request.redirect_url(trust_root, return_to) redirect_to(url)
昨日の日記では、鍵交換などの認証のための事前準備 (OpenID::Consumer#begin) のところを読んだ。 今日は認証サーバへのリダイレクトを生成する redirect_url メソッドについて調べよう。 昨日見たとおり、 request は SuccessRequest クラスのインスタンスになってる(GenericConsumer#begin メソッドの中で SuccessRequest クラスののインスタンスを生成している)。
def begin(service) nonce = self.create_nonce assoc = self.get_association(service.server_url) return SuccessRequest.new(assoc, nonce, service) end
SuccessRequest クラスも consumer.rb で定義されているっぽい。 定義されているメソッドの一覧を表示してみた。
$ grep -E '^\s*(class|def|module)' consumer.rb class OpenIDStatus def initialize(status) class SuccessRequest < OpenIDStatus def initialize(assoc, nonce, service) def redirect_url(trust_root, return_to, immediate=false) def return_to(return_to) def add_extension_arg(namespace, key, value) def add_arg(key, value) def uses_extension?(extension_url)
SuccessRequest#redirect_url
redirect_url の引数は trust_root, return_to, immediate の3つ。
- trust_root … 認証サーバがコンシューマを識別するための URL 。認証サーバが「許可しますか?」の画面を出すかどうかは、 trust_root を見ているんじゃないかな(未確認)。 realm みたいなものかと思っていたら、やっぱり 2.0 では openid.realm というパラメータに変更されてた。
- return_to … 認証サーバでのログイン後に戻ってくる URL 。 trust_root で指定した URL を含んでいないと NG になるはず(未確認)。
- immediate … immediate mode を使うかどうか。とりあえずは気にしないことにする。
メソッドの中身は意外とシンプルだった。 認証サーバに渡すパラメータをハッシュとして生成して、 OpenID::Util.append_args でパラメータを追加し、最後に to_s 文字列に変換しているだけ。
def redirect_url(trust_root, return_to, immediate=false) # add the nonce into the return_to url return_to = OpenID::Util.append_args(return_to, @return_to_args) redir_args = { "openid.identity" => @server_id, "openid.return_to" => return_to, "openid.trust_root" => trust_root, "openid.mode" => immediate ? 'checkid_immediate' : 'checkid_setup' } redir_args["openid.assoc_handle"] = @assoc.handle if @assoc redir_args.update(@extra_args) return OpenID::Util.append_args(server_url, redir_args).to_s end
redirect_url メソッドではインスタンス変数がいくつか使われている。 このうち、 @server_id と @return_to_args と @extra_args は initialize メソッドで初期化されてる。
def initialize(assoc, nonce, service) super(SUCCESS) @service = service @server_id = service.server_id @server_url = service.server_url @identity_url = service.consumer_id @extra_args = {} @return_to_args = {'nonce' => nonce} end
- @server_id … 認証サーバのID。 Consumer#begin で取得している。
- @return_to_args … nonce を含むハッシュ値。 nonce も Consumer#begin で生成している。
- @extra_args … OpenID の拡張として含む値。拡張を追加するには、 OpenID::SuccessRequest#add_extension_arg を呼び出せばいいみたい。
def add_extension_arg(namespace, key, value) @extra_args['openid.'+namespace+'.'+key] = value end
まとめ
今日は短めだった。
- SuccessRequest#redirect_url … ハッシュに OpenID のパラメータを格納し、最後に文字列 (URL) へと変換する。
- ちょっとインスタンス変数を多用気味かも。
- SuccessRequest#add_extension_arg … OpenID を拡張する際に呼び出す(未確認)。