TOP情報セキュリティ> 第2回:PHPで作ろうConsumer (2/3)




使って広がるOpenIDの輪

使って広がるOpenIDの輪

第2回:PHPで作ろうConsumer

著者:はてな  水野 貴明

公開日:2007/12/13(木)

サンプルの中身をみる

では、それぞれの動きについてみていきましょう。PHP-OpenIDはかなり高機能で、ほとんどのことを自動で行ってくれます。特にConsumerのサンプルは非常にシンプルだといえるでしょう。

まずindex.phpですが、こちらは単なる入力フォームを提供するだけの機能しかありません。「$msg」や「$error」など、いくつかの変数が存在していた場合に、それを表示する仕組みが用意されています。これは認証に成功や失敗した際などに利用されるもので、index.phpをincludeして使うために、用意されています。

FORM要素の送信先(action属性)には「try_auth.php」が指定されています。openid_identifierというクエリパラメータにIdentifierのURLが入ってtry_auth.phpが呼び出されることがわかります。

一番重要なのが、この「try_auth.php」です。こちらはOpenIDの認証処理のほぼすべてが含まれており、完全にPHPのコードのみで記述されています。なお処理の一部は、require_onceによって呼び出される「common.php」の内部に記述されています。

続いて、処理の基本的な流れを紹介します。処理はrun関数の中で行われ、その中で呼び出される「getConsumer(common.phpで定義されています)」で、Auth_OpenID_Consumerというクラスのインスタンスが生成されます。これがその名の通り、Consumerの処理を行うクラスです。

インスタンス生成の際に、認証情報を保存するための$storeオブジェクトを指定しています。このオブジェクトによって、情報の保存場所を変更できます。サンプルでは、getStore関数(common.php)内でAuth_OpenID_FileStoreクラスのインスタンスを生成し、ファイルとしてデータを保存しています。

PHP-OpenIDにはこれ以外にも、MySQLに保存する「Auth_OpenID_MySQLStore」をはじめとして、いくつかのクラス(Auth_OpenID_OpenIDStoreを継承したもの)が用意されており、どれを利用するかで、認証情報の保存方法を変えることができます。

サンプルでは、ファイルパスとして「/tmp/_php_consumer_test」を指定しているので、認証作業をした後にこのディレクトリを見れば、利用された情報を確認できます。データの保存場所は変更可能です。

Auth_OpenID_Consumerクラス、beginメソッド
図2:Auth_OpenID_Consumerクラス、beginメソッド
(画像をクリックすると別ウィンドウに拡大図を表示します)

ここで保存される情報は、ConsumerとIdPの間でやり取りされる際の「アソシエーションハンドル」や共通暗号鍵、nonceなどです。「アソシエーションハンドル」は、エンドユーザ(ログインしようとしているユーザ)、Consumer、IdPの間でのやり取りを特定するためのデータです。

共通暗号鍵(Shared Secret)は、正しいIdPとやり取りを行っているかを確認するために利用されています。またnonceは、なりすまし攻撃を防ぐために利用されるデータです。

さて、Auth_OpenID_Consumerクラスを生成すると、今度はそのbeginメソッドを呼び出します。その際に、取得したIdentifier URLを渡します。このメソッドは、Identifier URLからIdPの情報を読み込み、IdPにassociateと呼ばれるアクセスを行います。

このアクセスは「アソシエーションハンドル」や共通鍵を取得するためのものです。ただし、ここで得られる情報はキャッシュが可能で(保存先は$storeで指定したオブジェクトです)、キャッシュが存在していれば、このアクセスは省略され、キャッシュに保存されている情報が利用されます。

beginメソッドはAuth_OpenID_AuthRequestオブジェクトを返します。ここに、PAPEなどのいくつかの情報を追加した後、WebブラウザにIdPへのアクセスを促します。その際にConsumerは、Webブラウザに対してopenid.return_toとopenid.trust_rootという2つの情報をIdPに対して送信させます。これらは、認証作業が終わった後戻ってくるべきURLと、認証の対象とするサイト(つまりConsumer)のルートURLをあらわしています。

サンプルでは、これらの情報はそれぞれcommon.phpで用意されているgetReturnToとgetTrustRootという関数を使ってセットされます。return_toにはtry_auth.phpと同じディレクトリにあるfinish_auth.phpがセットされ、結果としてIdPでの認証後にこのファイルが呼び出されます。このファイル名を書き換えることで、認証終了処理を行う先を変更できます。

getTrustRootでは、$_SERVER['SERVER_NAME']などの変数を使い、やはり同じくtry_auth.phpが存在するURLがセットされます。IdPの確認画面などではこのURLが表示されます。ただし、getTrustRootではポート番号がセットされている場合もあります。また、try_auth.phpが存在するのは「http://example.com/openid/」だけど、認証したいのは「http://example.com/」である、といった場合には適さないため、内容を適宜書き換えて利用する必要があるでしょう。

IdPが呼び出されると、そちら側で認証の処理が行われ、openid.return_toで指定されたファイル、つまりfinish_auth.phpにリダイレクトされます。

finish_auth.phpでは、再びAuth_OpenID_Consumerクラスのインスタンスを生成し、completeメソッドを呼び出してAuth_OpenID_ConsumerResponseというオブジェクトを取得します。呼び出し時のクエリ文字列の情報から、認証の成功/失敗といった状況や認証時のデータの解析結果を保持しています。

このstatusプロパティをチェックすることで、認証の成功/失敗がわかります。成功の場合はAuth_OpenID_SUCCESS、認証がキャンセルされた場合はAuth_OpenID_CANCELとなります。finish_auth.phpでは、それに応じてメッセージを変数にセットし、index.phpをincludeしてそれを表示しています。

もし、実際にログインの仕組みとしてOpenIDのConsumerを実装し、認証に成功した場合は、ユーザ情報をデータベースに書き込んだり、セッションクッキーを発行するなどの処理をして、エンドユーザをログイン状態にする必要があるでしょう。 次のページ


前のページ  1  2  3  次のページ


株式会社はてな 水野 貴明
著者プロフィール
株式会社はてな  水野 貴明
1973年東京生まれ。エンジニア兼技術系ライター。株式会社はてな勤務。近著に「俺流Amazonの作り方」(アスキー)、「詳解RSS〜RSSを利用したサービスの理論と実践」(ディー・アート)など。趣味はラテン音楽と海外旅行と神輿。主な原稿の執筆場所はスターバックスと通勤電車の中。


INDEX
第2回:PHPで作ろうConsumer
  PHP-OpenIDを使ってみよう
サンプルの中身をみる
  Consumerの仕組みについてもう少し詳しくみてみよう