OAuth認証でTwitterを利用するWebアプリケーションの作り方を以前紹介しました。OAuth認証はさまざまなサイトで使われていますが、使い方がちょっとずつ違っていたりして、プログラミングが苦手な人には敷居が高い気がします。せっかくおもしろいことを思いついても、最初の段階で躓いて挫折するのはがっかりなので、簡単なサンプルがたくさんあるといいと思います。
というわけで、PHPでFacebookのOAuth認証を利用する例を紹介しましょう。
Facebookの開発者サイトでアプリケーションを登録し、アプリケーションIDとシークレットキーを取得します。

2つのファイルでOAuth(説明用)
OAuth認証の開始ページを/facebook/oauth-start.php、終了ページを/facebook/oauth-end.phpとします。
oauth-start.phpは次のようになります。おおざっぱなTwitterと比べて、Facebookでは、OAuth認証時に認可する機能をかなり細かく設定できます。ここでは、掲示板への登録を許可するように、「scope=publish_stream」をつけておきます。他の権限については、Extended Permissionsを参照してください。
<?php
session_start();
$_SESSION['application_id'] = アプリケーションID;
$_SESSION['application_secret'] = シークレットキー;
$_SESSION['redirect_uri'] = 'http://localhost/facebook/oauth-end.php';
$url = 'https://www.facebook.com/dialog/oauth'
. '?client_id=' . $_SESSION['application_id']
. '&redirect_uri=' . urlencode($_SESSION['redirect_uri'])
. '&scope=publish_stream'; //投稿する場合
?>
<!doctype html>
<html>
<head>
<title>OAuth Start</title>
</head>
<body>
<p><a href="<?php echo $url; ?>">OAuth</a></p>
</body>
</html>
oauth-start.phpが生成するURLにアクセスすると、認証画面になります。

「許可する」をクリックすると、oautu-start.phpで指定したリダイレクトURL(ここではhttp://localhost/facebook/oauth-end.php)にリダイレクトされます。oauth-end.phpでは、リダイレクトが伴うcodeというパラメータを利用して、認証を完了させます。(ちなみに、http://www.facebook.com/settings/?tab=applicationsで許可を取り消せます。)
<?php
session_start();
$cxContext = NULL;
$cxContext = stream_context_create(array(//プロキシサーバを利用する場合
'http' => array('proxy' => 'tcp://proxy.example.net',
'request_fulluri' => True)));
$url = 'https://graph.facebook.com/oauth/access_token'
. '?client_id=' . $_SESSION['application_id']
. '&client_secret=' . $_SESSION['application_secret']
. '&redirect_uri=' . $_SESSION['redirect_uri']
. '&code=' . $_GET['code'];
$result = file_get_contents($url, False, $cxContext);
$output = null;
parse_str($result, $output);
if (!isset($output['access_token'])) {
session_destroy();
die();
}
$_SESSION['access_token'] = $output['access_token'];
?>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>OAuth End</title>
</head>
<body>
<p>access_tokenをセッションに保存した。</p>
<p><a href="post.php">送信テスト</a></p>
</body>
</html>
oauth-end.phpで認証が完了したら、次のようなpost.phpで、メッセージを送信してみましょう。
<?php
session_start();
//セッションからaccess_tokenを復元する。
if(!isset($_SESSION['access_token'])) {
header('Location: http://localhost/facebook/oauth-start.php');
die();
}
$access_token=$_SESSION['access_token'];
session_destroy();
//投稿
require_once 'HTTP/Request2.php';
$url = "https://graph.facebook.com/me/feed"
. "?access_token=$access_token"
. '&message=' . urlencode("テスト at " . time());
$request = new HTTP_Request2($url, HTTP_Request2::METHOD_POST);
$request->setConfig(array(
//'proxy_host' => 'proxy.example.net',//プロキシサーバを利用する場合
//'proxy_port' => 3128,
'ssl_verify_peer' => false
));
$response = $request->send();
if ($response->getStatus() / 100 != 2) {
echo $response->getReasonPhrase();
die();
}
?>
<!doctype html>
<html>
<head>
<title>Message Post</title>
</head>
<body>
<p>投稿成功。</p>
<pre><?php echo $response->getBody(); ?></pre>
<p><a href="oauth-start.php">start</a></p>
</body>
</html>
例によって、PHPにはいろんなHTTPクライアントがあって、あまり整理されていないのですが、ここではHTTP_Request2を使っています(HTTP_Requestはプロキシ経由のSSL通信に対応していないため、ここでは使えません)。次のようなコマンドで、HTTP_Request2をインストールしておく必要があります。XAMPP for Windowsの場合、スタートメニューのコマンドプロンプトを右クリックして管理者として実行してください。プロキシが必要な環境では、事前に「set http_proxy=http://proxy.example.net:3128/」(Windows)や「export http_proxy=http://proxy.example.net:3128/」(Windows以外)が必要です。
cd \xampp\php
pear install http_request2
SSL通信のためには、PHPでOpen SSLが有効になっていなければなりません。Open SSLが有効かどうかはphpinfo()で確認できます。「OpenSSL suppor」がenabledになっていれば大丈夫です。有効になっていない場合は、php.iniに「extension=php_openssl.dll」という行を追加してください(XAMPPの場合はc:\xampp\php\php.ini)。「extension=」という記述がたくさんある場所に書いておけばいいでしょう。php.iniを変更したら、Apacheを再起動してください。
1つのファイルでOAuth+投稿
oauth-start.phpとoauth-end.php、post.phpを1つのファイル1click-post.phpにまとめると次のようになります。コールバック処理の最後で一度転送しているのは、ブラウザのアドレス欄にトークンを表示させないためです(セキュリティのためではありません)。
<?php
session_start();
$application_id = アプリケーションID;
$application_secret = シークレットキー;
$redirect_uri = 'http://localhost/facebook/1click-post.php';
if (!isset($_SESSION['access_token'])) {
if (!isset($_GET['code'])) {//OAuth
$url = 'https://www.facebook.com/dialog/oauth'
. "?client_id=$application_id"
. '&redirect_uri=' . urlencode($redirect_uri)
. '&scope=publish_stream'; //投稿する場合
header("Location: $url");
session_destroy();
} else {//コールバック
$cxContext = NULL;
//$cxContext = stream_context_create(array(//プロキシサーバを利用する場合
// 'http' => array('proxy' => 'tcp://proxy.example.net:3128',
// 'request_fulluri' => True,)));
$url = 'https://graph.facebook.com/oauth/access_token'
. "?client_id=$application_id"
. "&client_secret=$application_secret"
. "&redirect_uri=$redirect_uri"
. '&code=' . $_GET['code'];
$result = file_get_contents($url, False, $cxContext);
$output = null;
parse_str($result, $output);
if (!isset($output['access_token'])) {
session_destroy();
} else {
$_SESSION['access_token'] = $output['access_token'];
header("Location: $redirect_uri"); //トークン隠すための転送(オプショナル)
}
}
die();
} else {//投稿
$access_token = $_SESSION['access_token'];
session_destroy();
require_once 'HTTP/Request2.php';
$url = "https://graph.facebook.com/me/feed"
. "?access_token=$access_token"
. '&message=' . urlencode("テスト at " . time());
$request = new HTTP_Request2($url, HTTP_Request2::METHOD_POST);
$request->setConfig(array(
//'proxy_host' => 'proxy.example.net',//プロキシサーバを利用する場合
//'proxy_port' => 3128,
'ssl_verify_peer' => false
));
$response = $request->send();
if ($response->getStatus() / 100 != 2) {
echo $response->getReasonPhrase();
die();
}
}
?>
<!doctype html>
<html>
<head>
<title>Message Post</title>
</head>
<body>
<p>投稿成功。</p>
<pre><?php echo $response->getBody(); ?></pre>
</body>
</html>
お約束ですが、こういう話を基本から学びたいという方には、拙著『Webアプリケーション構築入門 実践!Webページ制作からマッシュアップまで 』(森北出版, 2011)がおすすめです。