Hatena::ブログ(Diary)

konisimple log RSSフィード

はてなブログに移転しました!

2011年01月16日

PHP(PEAR)でOAuth経由でGoogle Latitude APIを使う

PHPPEAROAuthを使ってGoogle Latitude APIを叩くことに成功したのですが、初めてのOAuthアプリということで結構苦戦したのでメモ。


さてOAuthのデモというとTwitterAPIを叩いたサンプルコードが多いんですが、TwitterAPIにはScopeなど引数をつけることがないので、そのままコピペでは他のAPIが叩けないサンプルが多いです。

そこで今回、Google Latitude APIを叩いてみましたのでご紹介します。たぶん日本語の「Google Latitude APIを叩いてみた」がないのでGoogleLatitudeにしましたが、基本的にGoogleOAuthを使うアプリであればこのコードを流用すれば動く気がします。

※今回のコードで動いているサンプルあこちら

PHP(PEAR)でOAuth経由でGoogle Latitude APIを使ってみた - konisimple

まずOAuthについて学びます

全体の流れはYahoo!の開発者向けドキュメントの図がとてもよいです。おすすめ。

Yahoo!デベロッパーネットワーク - OAuth - フロー

PEARとHTTP_OAuthを入れます。

OAuth関連の処理はリクエストの度に厳格な署名が必要だったりしてかなり煩雑です。

一度私も、スクラッチから書いたことがありますが、かなり面倒で挫折しましたw何かしらライブラリを使うことをおすすめします。

以下を参考にPEARとHTTP_OAuth、付随するライブラリを入れます。

PHPでTwitter APIのOAuthを使う方法まとめ - 頭ん中

GoogleのサイトでConsumer keyとConsumer secretを入手

https://www.google.com/accounts/ManageDomains

domainを入れます。Googleの場合はConsumer keyドメインになります。

GoogleのサイトでAPI keyを入手

https://code.google.com/apis/console/

Google Latitudekeyを取得。

f:id:konisimple:20110116151942p:image

これがキーです。

早速PHPを書いていきましょう!

全体のコードは最後にまとめて示します。

はじめに使う変数を最初に定義しておきます。URLもここに書いたのは、このコードをちょっと書き換えれば他のSP(ServiceProvider)でも動くからです。

<?php
include 'HTTP/OAuth/Consumer.php';
session_start();
$consumer_key = 'sample.net';
$consumer_secret = '[あなたのConsumer secret]';
$get_request_token='https://www.google.com/accounts/OAuthGetRequestToken';
$get_authorize='https://www.google.com/latitude/apps/OAuthAuthorizeToken';
$get_access_token='https://www.google.com/accounts/OAuthGetAccessToken';
$callback = '[コールバックするURL(このスクリプト設置先、もちろんhttp://から。)]';
$additional=array(
	"scope"=>"https://www.googleapis.com/auth/latitude",
	"domain"=>"sample.net"
);

この、10行目のscopeとdomainがポイントです。これがないと動きません。

Twitterのサンプルにはこれがないので地味に結構はまりポイントな気がします。

このへんのことは、ドキュメントのこのへんに書いてあります↓

scope

次はいよいよOAuth_Consumerクラスを使います。

<?php
$consumer = new HTTP_OAuth_Consumer($consumer_key, $consumer_secret);
$http_request = new HTTP_Request2();
//証明書は面倒なのでスルー。
$http_request->setConfig('ssl_verify_peer', false);
$consumer_request = new HTTP_OAuth_Consumer_Request;
$consumer_request->accept($http_request);
$consumer->accept($consumer_request);
if (empty($_SESSION['access_token']) && empty($_GET['oauth_verifier'])) {
	//初回の処理。ユーザに飛んでもらうURLを取得
	$consumer->getRequestToken($get_request_token, $callback, $additional);
	$_SESSION['request_token'] = $consumer->getToken();
	$_SESSION['request_token_secret'] = $consumer->getTokenSecret();
	$auth_url = $consumer->getAuthorizeUrl($get_authorize,$additional);
	header("Location: $auth_url");
}else{
	//2回目以降
	 if($_GET['oauth_verifier']){
	 	//SPから帰ってきた直後だった場合。アクセストークンを取得
		$consumer->setToken($_SESSION['request_token']);
		$consumer->setTokenSecret($_SESSION['request_token_secret']);
		$consumer->getAccessToken($get_access_token, $_GET['oauth_verifier']);
		$_SESSION['access_token'] = $consumer->getToken();
		$_SESSION['access_token_secret'] = $consumer->getTokenSecret();
	}else{
		//普通にアクセスが来た場合。既にアクセストークンがあるのでセットする
		$consumer->setToken($_SESSION['access_token']);
		$consumer->setTokenSecret($_SESSION['access_token_secret']);	
	}
	//ここにやりたいことを書く
}

これでOAuthができるはずです!

ちなみにデフォルトでちゃんとauthentication headerが送られています。

ここでのポイントはリクエストを送るたびにdomainとscopeを送ってしまうことです($additionalのこと)。

使ってみよう!

では早速、このユーザの現在地を取得してみましょう。

<?php
	$cr = new HTTP_OAuth_Consumer_Request;
	$response = $consumer->sendRequest('https://www.googleapis.com/latitude/v1/currentLocation?key=[さきほど取得したAPI KEY]',$additional,"GET");
	$data=json_decode($response->getBody());
	var_dump($data);

ここでリクエストにはAPI Consoleで取得したキーを付与します。Consumer keyではないのでご注意。

それからいちいちメソッドが違うのでご注意。DELETEとか使います。


参考

だいたいのことはリファレンスにのってます!

Docs For Class HTTP_OAuth_Consumer

scope

今回のコードで一部参考にさせていただきました。

PHPではてなのOAuth対応APIを使うチュートリアルっぽいの - 三等兵

※今回も私の環境ではこれでうまくいったよ!!というレポートです。

まとめ

以上をまとめると以下になります。

<?php
include 'HTTP/OAuth/Consumer.php';

session_start();

/*はてな
$get_request_token='https://www.hatena.com/oauth/initiate';
$get_authorize='https://www.hatena.ne.jp/oauth/authorize';
$get_access_token='https://www.hatena.com/oauth/token';
*/
/*Y!J
$get_request_token='https://auth.login.yahoo.co.jp/oauth/v2/get_request_token';
$get_authorize='https://auth.login.yahoo.co.jp/oauth/v2/request_auth';
$get_access_token='https://auth.login.yahoo.co.jp/oauth/v2/get_token';
*/
$consumer_key = '[yours]';
$consumer_secret = '[yours]';
$get_request_token='https://www.google.com/accounts/OAuthGetRequestToken';
$get_authorize='https://www.google.com/latitude/apps/OAuthAuthorizeToken';
$get_access_token='https://www.google.com/accounts/OAuthGetAccessToken';
$callback = '[yours]';
$additional=array(
	"scope"=>"https://www.googleapis.com/auth/latitude",
	"domain"=>"[yours]"
);

try{
	$consumer = new HTTP_OAuth_Consumer($consumer_key, $consumer_secret);
	
	$http_request = new HTTP_Request2();
	$http_request->setConfig('ssl_verify_peer', false);
	$consumer_request = new HTTP_OAuth_Consumer_Request;
	$consumer_request->accept($http_request);
	$consumer->accept($consumer_request);
	if (empty($_SESSION['access_token']) && empty($_GET['oauth_verifier'])) {
		$consumer->getRequestToken($get_request_token, $callback, $additional);
		$_SESSION['request_token'] = $consumer->getToken();
		$_SESSION['request_token_secret'] = $consumer->getTokenSecret();
		$auth_url = $consumer->getAuthorizeUrl($get_authorize,$additional);
		header("Location: $auth_url");
	}else{
		 if($_GET['oauth_verifier']){
			$consumer->setToken($_SESSION['request_token']);
			$consumer->setTokenSecret($_SESSION['request_token_secret']);
			$consumer->getAccessToken($get_access_token, $_GET['oauth_verifier']);
			$_SESSION['access_token'] = $consumer->getToken();
			$_SESSION['access_token_secret'] = $consumer->getTokenSecret();
		}else{
			$consumer->setToken($_SESSION['access_token']);
			$consumer->setTokenSecret($_SESSION['access_token_secret']);	
		}
		$cr = new HTTP_OAuth_Consumer_Request;
		$response = $consumer->sendRequest('https://www.googleapis.com/latitude/v1/currentLocation?key=[yours]',$additional,"GET");
		$data=json_decode($response->getBody());
	}
} catch (Exception $e) {
	echo "例外:", var_dump($e), "\n";
}
?>
<pre>
<?=var_dump($data)?>
</pre>

2010年10月09日

OpenCVを使わずにPHPで顔認識

PHPでOpenCVなしのピュアPHPで顔認識するクラスライブラリ「Face_Detector」:phpspot開発日誌という記事を読んで、ちょ!まじかよ!と思って実際に自分のサーバーに実装してみた。そしたら割とちゃんと認識していたけど、認識しない場合も結構多かった。

どんなもんか簡単に試せるようなWebアプリ書いてみたので、どんなもんか確かめるのにどうぞ。

OpenCVを使わずにPHPで顔認識 - konisimple

2010年06月20日

PHPのPEAR:HTTP_OAuthを利用して、twitterにoauthでログインしてみるテスト

twitterにoauthでログインしてみる - konisimple

勉強がてら、PHPPEAR:HTTP_OAuthを利用して、twitteroauthでログインしてみるテストのページを作ってみました。


昨日入れたブラウザベースのpear管理アプリがとても便利ですね。

ブラウザ上だけど新たなPEARライブラリ追加が超簡単!

実は一回本当に0からOAuthのコード書こうとしたんですが、signatureがやっかいで挫折しちゃったんですよね。

これからはほいほいライブラリとか使おうと思いましたw

参考

HTTP_OAuthを利用してTwitterのOAuth認証を行う @ php-tips

Yahoo!デベロッパーネットワーク - OAuth - フロー

2010年06月19日

250以上のドメインからwhois検索できるツール作った

WHOIS 情報検索ツール - konisimple

類似サービスはたくさんあると思いますが。

さっきインストールしたPEARのWHOIS使ったら簡単に出来た。

例によってjQueryAjaxになっている。

なんか最近はPHPとHTMLが混ざったものを書くよりphpでjson吐いてjQueryでパースさせるのがマイブームですね。

ブラウザでの処理が無駄に増えるけど、ページ遷移なしで検索できるの気持ちイイ!!ですよね!?

coreserverにpear入れました

coreserverにPEARというPHPライブラリのパッケージ管理ソフトを導入しました。

PEARって、たまにPHPのサンプルで使われてたりしますが、なんとなくむつかしそうで敬遠してたんですよね。

でも先駆者の方とオープンソースにかける頼もしい人たちのおかげで、とても簡単に導入できました!

SeeIn開発日誌 - 共有サーバ(CORESERVER.JP)で自由にPEARのインストールをするを参考にしました。

二つめは、チャンネルのアップデート作業です。

これは、コマンドラインからPEARを操作する場合と同じです。

なお、WEBインターフェースからだとアップデートが必要な場合、パッケージの検索を行った場合等に画面上部に「WARNING: channel "pear.php.net" has updated its protocols, use "channel-update pear.php.net" to update」と、警告が表示されますので、「channel-update pear.php.net」の部分のリンクをクリックし、アップデート作業を行いましょう。

とありますが、僕の環境では何故かうまくいかなかったので、とりあえず[Channel Management]の[Update All Channels]をしてみました。

これでいいのかな…?

これで簡単にpearライブラリを導入出来るようになりました!

2010年05月10日

strlen($str)==0じゃなくてempty($str)

ずっと変数が空かチェックするのに

strlen($_GET["q"])==0

ってかいてたけど

empty($_GET["q"])

の方が見やすくてスマート。


自己流だったので、こういう所で無駄なことしてたりするよね。

PHPでsession.use_trans_sid=1してもURLにセッションIDが不可されないときの対処法

ini_set('session.use_trans_sid', '1');
session_start();

や、PHP.iniに書き込むなどして、session.use_trans_sid=1としても、なぜかリンク先URLにSIDが自動で追加されないとき。

  • session.use_trans_sid=1より先にsession_start();している。
    • 順番は大切
  • リンクが相対パスでない

リファレンスには

注意: 相対URLでないURLは外部サイトを指していると仮定され、SID が追加されません。これは、SID を外部のサーバに開示することはセキュリティ上のリスクとなる可能性があるためです。

って書いてある*1けど、/から始まる絶対パス指定でもOK!

参考

8.2 セッションの継続