PHP OpenID library で OpenID クライアントを作ってみる

OpenIDって?

OpenIDはURL形式のIDで、複数サービスを同一アカウントで利用できる。
また、OpenIDの認証サーバは、自分が信頼できる、自分の情報を預けても良いサーバをユーザが選択できることが最大の利点。

・・・って感じなんだけど、まだまだ普及率が足りない。
認証サーバも選べるほど無いし、OpenIDを採用しているサービスもほとんど無い。

でも、こんな便利そーなもの使わにゃ損だよね。

詳しくはこちら→OpenID(Japan)


PHP OpenID library をインストール

OpenID Enabledってサイトで OpenID を利用するためのライブラリを配布しているようです。
ライブラリは、Python Ruby Perl PHP .NET Java それぞれのものが用意されています。

さっそく、PHP版をpearコマンドでインストール。
(リモートではダメだったので、ローカルに落としてからインストールした)

[PHP OpenID library]
http://www.openidenabled.com/openid/libraries/php


consumer のサンプルスクリプトを参考に Client Class 作った

ダウンロードファイルの中の「examples」フォルダにサンプルが入ってる。
server関連のサンプルもあるが無視。クライアントのサンプルは「consumer」フォルダの中にある。

んで、それらを参考に適当に Client Class 書いてみる。
<?php
/*
 * OpenidClient
 * 2007/05/28 C@NI xlune.com.
 */

require_once "Auth/OpenID/Consumer.php";
require_once "Auth/OpenID/FileStore.php";

Class OpenidClient {
	
	private static $singleton = null;
	private $client = null;
	private $response = null;
	
	private $options;
	private $_options = array(
		'trust_root'=>'',
		'process_url'=>'',
		'store_path'=>'/tmp/_php_openid_client'
	);
	
	private $extensions = array();
	
	
	/*
	 * コンストラクタ
	 * @param Array オプションセット
	 */
	private function __construct($options=array())
	{
		session_name('_openid_auth');
		session_start();
		$this->options = array_merge($this->_options,$options);
		
		if(!file_exists($this->options['store_path'])) die("Could not open directory '{$this->options['store_path']}'.");
		
		$store = new Auth_OpenID_FileStore($this->options['store_path']);
		$this->client = new Auth_OpenID_Consumer($store);
		
		if(isset($_GET['openid_mode']) && ($_GET['openid_mode'] == 'id_res' || $_GET['openid_mode'] == 'cancel')){
			$this->response = $this->client->complete($_GET);
		}
	}
	
	
	/*
	 * インスタンス取得
	 * @param Array オプションセット
	 */
	public static function getInstance($options=array())
	{
		if (OpenidClient::$singleton == null) {
			OpenidClient::$singleton = new OpenidClient($options);
		}else{
			$this->options = array_marge($this->_options,$options);
		}
		return OpenidClient::$singleton;
	}
	
	
	/*
	 * OpenID認証URL
	 * @param String OpenID
	 */
	public function getAuthURL($openid)
	{
		$auth_request = $this->client->begin($openid);
		if (!$auth_request) return false;
		
		if(sizeof($this->extensions) < 1) $this->add();
		
		foreach($this->extensions as $val){
			$auth_request->addExtensionArg($val['namespace'], $val['key'], $val['value']);
		}
		
		$redirect_url = $auth_request->redirectURL(
			$this->options['trust_root'],
			$this->options['process_url']
		);
		
		return $redirect_url;
	}
	
	
	/*
	 * リクエスト追加
	 * @param String Namespace  default "sreg"
	 * @param String Key        "required" or "optional"
	 * @param String value(s)   "nickname,email,fullname,dob,gender,postcode,country,language,timezone"
	 */
	public function add($namespace='sreg', $key='optional', $value='nickname,email,fullname,dob,gender,postcode,country,language,timezone')
	{
		array_push($this->extensions, array(
				'namespace'=>$namespace,
				'key'=>$key,
				'value'=>$value
			)
		);
	}
	
	
	/*
	 * セットオプション
	 * @param String Key
	 * @param String Value
	 */
	public function setOption($key,$val)
	{
		$this->options[$key] = $val;
	}
	
	
	/*
	 * レスポンスチェック
	 */
	public function isResponse()
	{
		if($this->response != null){
			return true;
		}
		return false;
	}
	
	
	/*
	 * レスポンスステータス
	 * @res Number 0:失敗 1:成功 2:ユーザキャンセル
	 */
	public function getStatus()
	{
		if(!$this->isResponse()) return 0;
		
		switch($this->response->status){
			case Auth_OpenID_SUCCESS:
				return 1;
				break;
			case Auth_OpenID_CANCEL :
				return 2;
				break;
			default :
				return 0;
		}
	}
	
	
	/*
	 * IdentityURL
	 */
	public function getIdentityURL()
	{
		if($this->getStatus()==1){
			return $this->response->identity_url;
		}
		return '';
	}
	
	
	/*
	 * canonicalID
	 */
	public function getCanonicalID()
	{
		if($this->getStatus()==1){
			if ($this->response->endpoint->canonicalID) {
				return $this->response->endpoint->canonicalID;
			}
		}
		return '';
	}
	
	
	/*
	 * ExtensionResponse
	 * @param String Namespace
	 */
	public function getExtension($namespace='sreg')
	{
		if($this->getStatus()==1){
			return $this->response->extensionResponse($namespace);
		}
		return array();
	}
	
}



動作テスト

OpenID クライアントサンプル

うん、認証おーけー。
これで、新サービスとか始めるときはOpenIDが使えるね、というかOpenIDだけにしよう。

ちなみに、livedoorのOpenIDは認証自体はできるが、認証後に返ってくるはずのユーザ情報を返してくれない。
仕様なのかセキュリティ制限なのかは不明。


--
なんかもう、技術的に作る側には行けないなぁ。私は使わせてもらう側の人間だ。
Name
Email
Your website or blog
Comment
Security code (CAPTCHA™)