web-dev-qa-db-ja.com

Facebookでセッションとアクセストークンを適切に処理する方法PHP SDK 3.0?

PHP 3.0 SDKには、getSession()またはFacebook APIの外部からのセッション処理はありません。先日、facebookの開発者はJavaScript SDKを何らかの形で更新しました。 このブログエントリおよびこのバグレポート

ここ数日のうちに、ホストされたJS SDKに変更が導入され、現在のPHP SDK(2.xおよび3.x)との互換性がすべて失われました。 JSおよびPHP SDKのWebサイトでは、サーバー側APIのエラーが発生する可能性があります。

ただし、それが本当に私の問題に影響するかどうかはわかりません。同様にこの質問の答えOAuthダイアログのアクセストークンを取得していますPHPそしてセッションに新しいアクセストークンを保存します。

現在の回避策

次のコードは、このセッションの処理方法を示しています。 $_REQUEST['session']は、OAuthダイアログの応答の内容です。

if(isset($_REQUEST['session'])) {

    $response = json_decode(stripslashes($_REQUEST['session']), true);

    if(isset($response['access_token'])) {
        $this->api->setAccessToken($response['access_token']);
        $_SESSION['access_token'] = $this->api->getAccessToken();
    }

}
elseif(isset($_SESSION['access_token']) && ! isset($_REQUEST['signed_request'])) 
    $this->api->setAccessToken($_SESSION['access_token']);
elseif(isset($_REQUEST['signed_request'])) {
    Session::invalidate('fbuser');
    $_SESSION['access_token'] = '';
}

ユーザーデータの処理方法は次のとおりです。

try {
    $this->user = Session::getVar('fbuser');
    if ($this->user === false || is_null($this->user)) {
        $facebookUser = $this->api->api('me?fields=id,name,first_name,last_name');
        $this->user = new FBUserModel(array('fbId' => $facebookUser['fbId'], ...));
        Session::setVar('fbuser', $this->user);
    }
}


問題

テスト中はすべて正常に見えます。一度エラーが発生した場合のみ:許可が設定された後の最初の時間。これで、アプリはオンラインになっているため、平均して2人のユーザーすべてでエラーが発生しているように見えます

$facebookUser = $this->api->api('me?fields=id,name,first_name,last_name');

エラー付き:

An active access token must be used to query information about the current user.


質問

なぜこれが起こっているのですか?エラーは、ユーザーがアプリの認証とアクセストークンが変更された後に初めてアプリを起動したときにのみ発生するため、デバッグが非常に困難です。そして、それでも毎回起こっているわけではありません。新しいPHP SDKを使用して、セッションとアクセストークンをどのように処理する必要がありますか?

どんな助けも大歓迎です!


編集

いくつかのIE iFrame内のCookie /セッションに問題があることがわかりました。このブログ投稿。そのヒントといくつかのさらなる調査により、ブートストラップに次の行を追加しました。

ini_set('session.use_trans_sid', 1);
header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');

これではるかに改善されましたが、50人のユーザーのうち約2人の情報は、ステップのランディングページ(認証)->フォーミュラ->登録の間で失われます。だから、私が見逃したものがまだあります。


編集2

からユーザー処理を編集しました

if ($this->user === false || is_null($this->user)) {
    // get user data
}

if ((is_object($this->user) && $this->user->fbId == '') || $this->user === false || is_null($this->user)) {
    // get user data
}

これは少し役立つようです。主な問題は私のセッションのどこかにあると思います。

さらに、アプリのどこかにFacebook OAuthExceptionがスローされるかどうかを確認するために、try/catchブロックを追加しました。この場合、上の場所をFacebookページとタブにリダイレクトして、新しい署名済みリクエストを取得します。これはこの問題を解決するのに役立つかもしれませんが、ユーザーをリダイレクトする必要がないようにアプリを防ぎたいです。


編集3

数日間の集中的なデバッグとログ記録の後、$_REQUEST['session']FB.ui permissions.requestメソッドから来るものはまれに空です。

以下がその処理方法です。

これは私がいつも含めていたものです:

FB.provide("UIServer.Methods", {'permissions.request': {size : {width: 575, height: 300}, url: 'connect/uiserver.php', transform : FB.UIServer.genericTransform}});

そして、この関数はフォーム送信時に呼び出されます。常に私のために働いたが、どういうわけかそれはまだフォームを送信しますsession == ''

function getPermission(form) {

    session = $('#' + $(form).attr('id') + ' input[name="session"]');

    if($(session).val() != '') {
        form.submit();
        return;
    }

    FB.ui({method: "permissions.request", "perms": 'user_photos'}, function callback(info){
        if(info.status=='connected' && info.session !== null) {
            $(session).val(JSON.stringify(info.session));
            form.submit();
        }
    });
    return;
}
37
Sascha Galley

私の解決策

まあ、私がやったことはすべて新しいJS SDKがリリースされるまでの回避策であったため、ベストプラクティスはないようです。 session.use_trans_sidを1に設定し、P3Pヘッダーを追加すると、IE iFrame Cookieの問題を解決するのに役立ちました(最初の編集を参照)。 uiのpermission_requestは、新しいアクセストークンを毎回送信しません(<5%)。

これが発生した場合、何かがおかしくなりました。しかし、この小さな何かが私を夢中にさせています。これはまれにしか発生しないため、ユーザーをフェイスブックタブにリダイレクトして、新しい署名付きリクエストを取得することができます。新しいJS SDKでは、うまくいけば、これはもう起こらないでしょう。

更新:最終ソリューション

私が監督したものが1つあり、解決策はここにあります: FBは定義されていない問題です
JS SDKを非同期にロードしませんでした!これはすべてを説明します。 all.jsファイルが十分な速度でロードされなかったため、JSエラーが発生したことがありました。そのため、許可ダイアログもJS検証も機能せず、空の#session入力値が送信されました。

5
Sascha Galley

私は今PHP SDK 3.xを問題なく使用しています。

クラス作成者のNaitikはgetSession()関数を削除しました。ユーザーが認証されているかどうかを知りたい場合は、getUser()を使用してください。

アクセストークンの場合、非常に簡単です。この関数getAccessToken()を使用すると、アクセストークンを取得してGraphまたはRest APIを呼び出すことができます。

$user = $facebook->getUser();

if ($user) {
//USER Logged-In
}
else {
//USER not Logged-In
}

//TO GET ACCESS TOKEN
$access_token = $facebook->getAccessToken();


//MAKE AN API CALL WITH IT
$user_info = $facebook->api('me?fields=id,name,first_name,last_name&access_token='.$access_token);
10
Hamza

手始めに、もう少しデバッグします。要求の内容を記録します。 $ _SESSIONに保存されるもの、$ _ REQUESTに渡されるもの。また、ブラウザの問題かどうかを確認します(ブラウザに関係なく発生していますか、それともパターンがありますか?)

しかし、IE(P3Pヘッダー)のCookieの問題を修正したため、サードパーティのCookieを拒否するブラウザーが残っていると思います。私が知る限り、SafariとOperaはデフォルトでこれを行います。さらに、このエラーはaccess_token無効または期限切れのものとは対照的に提供されます。

これをテストするには、サードパーティのCookieを無効にし( firefoxのabout:configを使用 など)、アプリの認証を解除します( Facebookのプライバシー設定)の下部にある[アプリとウェブサイト]セクションを使用します )、Cookie(キャンバスURLに関連する)を削除してから、アプリケーションを起動します。

ところで、 バグ17236に記載

2

こんにちは、私は同じトラブルで実行しましたが、ユーザー情報が読める場合はJS APIを見てPHP-SDKログインページにリダイレクトして解決したようです

例:

<script language="JavaScript">

function check_fb_status(){
    FB.api('/me', function(response){
     if(response.name) window.location='<?php echo $facebook->getLoginUrl(); ?>';
     else check_fb_status();
    });
}

check_fb_status();

</script>

スクリプトが成功した場合、ログインページがロードされ、ユーザーはJSとPHP SDK;)の両方で認識されます

1
benny

参考までに、Facebookは、PHP SDKの更新を約2時間前に投稿しました。これは、JavaScript SDKを使用してクライアントでセッションを作成する場合、新しいCookie形式のサポートを追加します。 Facebook PHP-SDK GitHubリポジトリ にあります。

0
Rob DiMarco