ZendFrameworkにもOpenIDを利用するためのコンポーネントが用意されてます。
まずは利用するためのサンプルコード
$id = $_POST['id'];
require_once 'Zend/OpenId/Consumer.php';
$consumer = new Zend_OpenId_Consumer();
if (!$consumer->login($openlogingid)){
echo 'OpenID 認証に失敗しました。';
}
上記のコードで認証サーバにリダイレクトされます。
そこで認証し、戻ってきたパスで次のコードを実行します。
require_once 'Zend/OpenId/Consumer.php';
$consumer = new Zend_OpenId_Consumer();
if ($consumer->verify($_GET, $id)) {
echo '認証に成功しました。';
} else {
echo 'OpenID 認証に失敗しました。'. $id);
}
これで、OpenIDに不正な情報等が含まれていなければ認証が完了です。
ただし、ZendFrameworkのOpenIDのコンポーネントとPHP OpenID Library(POL)とでは認証後のIDの検証方法が違うらしいです。
認証がPOLで成功し、ZendFrameworkで失敗することがあります。
YahooのOpenIDが対象となります。
Yahoo以外ですとOpenID2.0の仕様が失敗している気がします。
処理を確認するとZendFrameworkが失敗する原因は下記のコードにあるようです。
$id = $params['openid_claimed_id'];
if (!$this->_discovery
($id, $discovered_server, $discovered_version) ||
(isset($params['openid_identity']) &&
$params["openid_identity"] != $id) ||
(isset($params['openid_op_endpoint']) &&
$params['openid_op_endpoint'] != $discovered_server) ||
$discovered_version != $version) {
return false;
}
verifyメソッドの一番最後のif文ですが、$params["openid_identity"] != $idがtrueになってしまうため、verifyが失敗している模様です。
そもそも、claimed_idにはゴミ情報の#xxxが含まれるから、実際の送信したidentityとは内容が異なるはずなので、必ずここは不一致が成立してしまうような気がします。
ひとまず今はPOLを利用しているのですが、ZendFrameworkのバグでしょうか?
それともOpenID2.0の仕様なのでしょうか?
とりあえずは問題なく動作するライブラリで対処してしまいましょう。