PHP OpenID を使う (2)
RubyKaigi 2007 の日なのに PHP を使う。
先日の続きで PHP OpenID を使う話。 今日は認証サーバへリダイレクトするときのサンプルコードの中身を見てみよう。 やっていることは、たぶんこんな感じ。
- ユーザが入力した ID(URL)を受け取る
- URL から認証サーバを探す
- OpenID のリクエストを付けて認証サーバへ送る
共通部分 (common.php)
Consumer で使うクラスは以下の2つ。
- FileStore … Consumer が使うデータ (nonceなど) を格納
- Consumer … OpenID のクライアント
サンプルコードでは common.php でこのクラスを生成している。
require_once "Auth/OpenID/Consumer.php"; require_once "Auth/OpenID/FileStore.php"; $store_path = "/tmp/_php_consumer_test"; $store = new Auth_OpenID_FileStore($store_path); $consumer = new Auth_OpenID_Consumer($store);
認証サーバへのリダイレクト (try_auth.php)
エラー処理を省略すると、やっていることは以下の部分になる。
$openid = $_GET['openid_url']; $auth_request = $consumer->begin($openid); $auth_request->addExtensionArg('sreg', 'optional', 'email'); $redirect_url = $auth_request->redirectURL($trust_root, $process_url);
思ったよりもシンプルだった。
- $consumer->begin … ユーザが入力したIDから AuthRequest を生成
- $auth_request->addExtensionArg … 認証サーバに対して追加の属性 (email) を要求する
- $auth_request->redirectURL … 認証サーバへのリダイレクト先を取得する
最後の redirectURL の引数で渡している $trust_root と $process_url は以下のとおり。
$process_url = sprintf("$scheme://%s:%s%s/openid/finish_auth.php", $_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'], dirname($_SERVER['PHP_SELF'])); $trust_root = sprintf("$scheme://%s:%s%s", $_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'], dirname($_SERVER['PHP_SELF']));
trust_root は現在のディレクトリで、 process_url はそのディレクトリの finish_auth.php になってる。 自分でアプリを作るときは、 trust_root に固定文字列を渡して process_url は動的な文字列を渡すようにするのかな。よく分かってない。 Yet Another Hackadelic - ソースから読むOpenID (1)が参考になりそう。
$auth_request->redirectURL の戻り値に含まれるクエリは以下の通り。
action | openid&openid |
identity | http%3A%2F%2Fmachu.videntity.org%2F |
openid.mode | checkid_setup |
openid.return_to | http%3A%2F%2Fwww.machu.jp%3A80%2Fopenid%2Ffinish_auth.php%3Fnonce%3DOX2ioGxj |
openid.sreg.optional | |
openid.trust_root | http%3A%2F%2Fwww.machu.jp%3A80%2Fopenid |
以下のようにLocation を返し、認証サーバへリダイレクトさせる。
header("Location: ".$redirect_url);
認証サーバから認証結果を受け取る (finish_auth.php)
次は認証サーバからの認証結果を受け取るところ。 肝心な箇所だけを抜き出すとこうなる。
$response = $consumer->complete($_GET); if ($response->status == Auth_OpenID_SUCCESS) { $openid = $response->identity_url; }
認証サーバからの戻り値は、 Auth_OpenID_CANCEL, Auth_OpenID_FAILURE, Auth_OpenID_SUCCESS の3種類があるみたい。 Auth_OpenID_SUCCESS の場合は、 $response->identity_url で利用者の ID が取得できる。 ちなみに、サンプルコードでは、追加の属性(メールアドレスなど)を取得するところも含まれている。 昨日のエラーは、たぶん $consumer->complete で出ているので、あとはライブラリの中を見ていこう。