Hatena::ブログ(Diary)

konisimple log RSSフィード Twitter

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

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>

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/konisimple/20110116/1295159992
Connection: close