localhost環境で、Facebook のJavaScript APIでOAuth認証をする

FacebookのJavaScript SDKでOAuthを使ったアプリを、localhost環境で開発するための設定方法です。FacebookのJavascript SDKを利用すると、ログインしているユーザーやウォールの情報を取得できます。ただし、FB.loginを呼ぶ際に、Facebookがページのドメイン名をチェックするので、localhost/test.html のようなURLだと、「The specified URL is not owned by the application」というエラーが発生する。それを防ぐために、localhost.goodpic.com というようなサブドメインを、ローカルのホストに設定します。

まずは、Facebookでの設定。Facebook developers から、アプリを選択して、[Settings] > [Basic] を選択。 App Domain にサブドメイン無しのドメイン名(example.com)を入力する。ただし、その下の Website : Site URL: にhttpあるいはhttps から始まるサイトのURL(http://www.example.com) も忘れずに入力しておかないと、App Domainが正しく保存されません。

Facebookアプリをサブドメインで利用できるように

設定を保存したら、ローカル環境のhostsを書き換える。Macの場合はターミナルから、

% sudo emacs /private/etc/hosts    

以下を指定。

127.0.0.1       localhost local.goodpic.com

ターミナルから、hostsの情報をフラッシュする。

% sudo dscacheutil -flushcache    

例えば、test.htmlなどのHTMLファイルに以下を記入し、

<div id="fb-root"></div>
<script src="./facebook.js"></script>
<div id="fb-page"></div>

facebook.js ファイルでは、Facebook JavaScript ライブラリを非同期に読みこんでログイン処理をする。MAMPなど、ローカルでHTTPサーバを立ち上げて、http://local.goodpic.com/test.html にブラウザからアクセスすると、OAuth 認証が通った authResponse が正しく返ってきます。

window.fbAsyncInit = function() {
  FB.init({
    appId      : 'YOUR_APP_ID',
    channelUrl : 'YOUR_CHANNEL_URL',
    oauth      : true,
    status     : true, // check login status
    cookie     : true, // enable cookies
    xfbml      : true  // parse XFBML
  });
  // Additional initialization code here

  // Fetch facebook page infromartion
  FB.api('/215071268504237', function(res) {
    var widget = ['<h3>Page Information</h3><ul>'];

    for (var key in res) {
      widget.push('<li>',key,' = ',res[key],'</li>');
    }
    widget.push('</ul>');
    $('#fb-page').append(widget.join(''));
  });

  FB.login(function(res) {
    if (res.authResponse) {
      
      FB.api('/me', function(res) {
        console.log('Good to see you, ' + res.name + '.');
      });

      FB.api('/215071268504237/feed', function(res) {
        var widget = ['<h3>Page messages</h3>'];
        console.log(res);

        for (var i = 0, len = res.data.length; i < len; i++) {
          widget.push('<textarea style="width: 500px;" rows="5">', res['data'][i]['message'],'</textarea><br />');
        }
        widget.push('');
        $('#fb-page').append(widget.join(''));
      });

    } else {
      $('#fb-page').append('<p>Login required to browse page messages.</p>');
    }
  });
};

// Load the SDK Asynchronously
(function(d){
  var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
  js = d.createElement('script'); js.id = id; js.async = true;
  js.src = "//connect.facebook.net/ja_JP/all.js";
  d.getElementsByTagName('head')[0].appendChild(js);
}(document));