Home » PHP, Programing » symfonyでOpenIDを実装してみた

Check     このエントリーをはてなブックマークに追加

前々回、OpenIDが流行ってないと書いたが、OpenIDに賛同する気があるなら積極的に実装すべきかと思い、symfonyから簡単にコンシューマー部分を実装してみた。

symfonyにはsfOpenIDPluginという、OpenIDをかなり簡単に実装できるプラグインがあるが、Smart Modeに対応していないこと、OpenID 2.0に対応していないこともあり、別のPHPライブラリである、PHP OpenID Libraryを利用してみる。

なお、詳しい実装の流れは@ITのOpenID特集サイトが詳しい。

まずは、 PHP OpenID Libraryから2.x.x系のライブラリをダウンロード、解凍した中にある「Auth」ディレクトリをsymfonyプロジェクトの「lib」ディレクトリに配置しておこう。

こんな感じ

[project]/apps
[project]/web
…..
[project]/lib/Auth

詳しい実装の話は抜きにして、

/openid/login  ⇒ /openid/tryauth ⇒ OpenID供給サイト(Idp)  ⇒ /openid/finishauth

こんな感じで、太字になっている部分をサイト側は実装すればよい。

まずはmoduleのさくせい。
$ symfony init-module project openid

まずはloginフォーム
loginSuccess.php
[php]

OpenID
40)) ?>


[/php]

実装コードは下記のようになった。
action.class.php
[php]
class openidActions extends sfActions
{
/*
* ログインフォームを表示する処理
*/
public function executeLogin()
{
return sfView::SUCCESS;
}
/*
* ログインフォームからPostされたときのバリデート処理
*/
public function validateTryauth()
{
// OpenIDライブラリがNoticeを出してしまうため止めてます。
$er = error_reporting();
if ($er > E_STRICT) {
error_reporting($er – E_STRICT);
}

// openid_identifierがユーザの入力したURLが入っている。
$openid = $this->getRequestParameter(‘openid_identifier’);
if (!$openid)
{
// エラー処理は手抜き。。
$this->getRequest()->setError(‘openid_identifier’, ‘error’);
return false;
}
// openidの認証ファイルを格納するディレクトリ(DBにもできる)
$store_path = ‘/tmp/_php_tmp’;
if (!file_exists($store_path) && !mkdir($store_path))
{
$this->getRequest()->setError(‘openid_identifier’, ‘error’);
return false;
}

$store = new Auth_OpenID_FileStore($store_path);
$consumer = new Auth_OpenID_Consumer($store);
$auth_request = $consumer->begin($openid);
if (!$auth_request)
{
$this->getRequest()->setError(‘openid_identifier’, ‘error’);
return false;
}
//認証時に属性が欲しい場合は指定する。
$sreg_request = Auth_OpenID_SRegRequest::build(
array(‘nickname’),
array(‘fullname’, ‘email’));
if ($sreg_request)
{
$auth_request->addExtension($sreg_request);
}

//OpenID1.0
if ($auth_request->shouldSendRedirect())
{
// trust_rootは認証されるサイトのURL、return_toは認証後にこちらにリダイレクトするURL
$redirect_url = $auth_request->redirectURL(
‘http://sample.net/’,
‘http://sample.net/openid/finishauth’);
if (Auth_OpenID::isFailure($redirect_url))
{
$this->getRequest()->setError(‘openid_identifier’, ‘error’);
return false;
}
else
{
$this->redirect($redirect_url);
}
}
//OpenID2.0
else
{
$form_id = ‘openid_message’;
// trust_rootは認証されるサイトのURL、return_toは認証後にこちらにリダイレクトするURL
$form_html = $auth_request->formMarkup(
‘http://sample.net/’,
‘http://sample.net/openid/finishauth’,
false, array(‘id’ => $form_id));
if (Auth_OpenID::isFailure($form_html))
{
$this->getRequest()->setError(‘openid_identifier’, ‘error’);
return false;
}
else
{
$this->getRequest()->setAttribute(‘openid_html’, $form_html);
$this->getRequest()->setAttribute(‘form_id’, $form_id);
return true;
}
}
}
/*
* ログインフォームからPostされたときの処理
*/
public function executeTryauth()
{
}
public function handleErrorTryauth()
{
$this->forward(‘openid’, ‘login’);
}
/*
* Idpからリダイレクトされてからの処理
*/
public function executeFinishauth()
{
$er = error_reporting();
if ($er > E_STRICT) {
error_reporting($er – E_STRICT);
}
$store_path = ‘/tmp/_php_tmp’;
if (!file_exists($store_path) && !mkdir($store_path))
{
$this->getRequest()->setError(‘openid_identifier’, ‘error’);
$this->forward(‘openid’, ‘index’);
}
$store = new Auth_OpenID_FileStore($store_path);
$consumer = new Auth_OpenID_Consumer($store);

$response = $consumer->complete(‘http://sample.net/openid/finishauth’);
if ($response->status == ‘cancel’)
{
$this->getRequest()->setError(‘openid_identifier’, ‘error’);
$this->forward(‘openid’, ‘index’);
}
else if ($response->status == ‘failure’)
{
$this->getRequest()->setError(‘openid_identifier’, ‘error’);
$this->forward(‘openid’, ‘index’);
}
else if ($response->status == ‘success’)
{
//認証されたopenid
$openid = $response->getDisplayIdentifier();
//ここに認証処理を書けばよい例えば下記のような感じで。
$this->getUser()->setAuthenticated(true);
$this->getUser()->addCredential(‘editor’);
$this->getUser()->setAttribute(‘openid’, $openid, ‘user’);

//どこかにリダイレクトでも
$this->redirect(‘/top/index’);
}
}
}
[/php]

処理の流れがわかるように、アクションクラスにすべてつめこんでます。

そして、POST送信用に下記のファイルを用意する。
tryauthSuccess.php
[php]

*/