2013年9月26日木曜日

facebook APIで「an active access token must be used to query information about the current user」が出てしまう原因の解決方法

  • このエントリーをはてなブックマークに追加

最近のwebアプリやwebサイトでは会員システムを簡易化したり、
ソーシャル的な連携を強めるためにだったり、
登録に必要な情報を簡単に入力するためだったり、
という理由でfacebookログインが使われる事が多い。

APIで色んな情報が取れるし便利だし、
セッションはFacebookのセッションを使い回せるから会員サイトを作るのはすごく楽になる。

ということで導入してみたはいいものの、
なぜか$facebook->api("/me")を実行すると
an active access token must be used to query information about the current user
というエラーが出てしまってうまくいかないという事がたまにあったりする。

ネットで調べてもはっきりと解説が書いていなかったりするようなこともあったりするし、
なので今回はそれを解決するために自分が行った事を書いていきたいと思う。

  1. $facebook->getUser()をcallback先で使うようにする
  2. アプリの設定でドメインは入れているか、サンドボックスモードになってないか
  3. アプリの設定でwebサイトのURLはちゃんと入れているか(最後に/が入ってるか)
  4. ドメインの違いは大丈夫か?

1.$facebook->getUser()をcallback先で使うようにする

facebookのログイン認証が終わってリダイレクトされた先で何もしないのはNGということ。
なので基本的にcallbackのページでは下記のようにしたほうがよい。

// callback.php
$facebook = new Facebook(array(
  'appId' => "xxxxxxxxxxxx",
  'secret' => "xxxxxxxxxxxx"
));
$user = $facebook->getUser();
$me = $facebook->api("/me");

header("Location: index.php");
exit();
上記のようにする事で、Facebookクラス内に存在するuser:protectedやaccessToken:protected内にちゃんと値が入るようになり、
他のページに行ってもちゃんとAPIを使用する事が出来るようになる。

2.アプリの設定でドメインは入れているか、サンドボックスモードになってないか

赤枠内にちゃんとドメインの設定を行っているか!
青枠内が有効にするになっていないか!
というのをちゃんと設定しておくとエラーが出てくるということは無いと思う。
www.hogehoge.com、hogehoge.comと2つ指定しておくといいかも。

3.アプリの設定でwebサイトのURLはちゃんと入れているか(最後に/が入ってるか)

これは正直エラーと関係はないのかもしれないけど、
http://www.hogehoge.com/と入れてあげたほうがよいかも。

4.ドメインの違いは大丈夫か?

自分の場合はこれが原因だった
これはどういうことかというと、login.phpを実行したドメインとcallback.phpのドメインが違うということになる。
作り方にもよるんだけど、基本的なfacebookのログインの流れって下記になるはず。

1.login.phpにアクセス
  $facebook = new Facebook($arg)を実行
2.login.phpからfacebookにリダイレクト、facebookで認証
3.認証が完了後、callback.phpにリダイレクト
  $facebook = new Facebook($arg)と$facebook->getUser()を実行

この1のときにwww無し、3のときにwww有りだとうまくいかないということになる。
理由としてはfacebookとしてはwww無しのサイトを認証したのであり、
www有りのサイトを認証したわけではないから。

ということでこれの解決策としては下記がよいかと。

// callback.php
$facebook = new Facebook(array(
  'appId' => "xxxxxxxxxxxx",
  'secret' => "xxxxxxxxxxxx"
));
$user = $facebook->getUser();

try{
  $me = $facebook->api("/me");
}
catch(FacebookApiException $e){
  $login_url = $facebook->getLoginUrl(array(
    'redirect_uri' => "http://www.hogehoge.com/callback.php",
    'scope' => "xxxxxx"
  ));

  header("Location: $login_url");
  exit();
}

header("Location: index.php");
exit();
try catch構文を使って、エラー時に再度ログインをさせるようにすればいい。
これを行えばちゃんとwww有りの状態でfacebookの認証が行われる事になる。

人によってはOKだけど人によってはNGという謎の自体に陥っていたけど、
レンタルサーバにdnsとしてドメインを振っていたから、
www有りでもwww無しでもアクセスが出来るようになっていたのが今回の原因。

もう一つの解決手段としてはサイトにアクセスした時点でwwwが付いてなければwww有りにリダイレクトするというのがある。

個人的にはアクセス時点でリダイレクトをしてあげるというのが一番いいかも。
特にツイートするボタンとかをどう設定しているかとかにもよるけど、
外に出るURLがwww有りとかwww無しとか統一されていないと気持ち悪いし。

ということで意外と見落としがちなwww有り無し問題。
人に使ってもらうサービスを作るならこういうのはつきものだし、ちゃんとしていこうと思う。

Adsense