web-dev-qa-db-ja.com

CSRF状態トークンが提供されたものと一致しませんFB PHP SDK 3.1.1 Oauth 2.0

サーバーのログに、「CSRF状態トークンが提供されたトークンと一致しない」というエラーが表示されます。これは、ほとんどすべてのユーザーに発生するようです。ただし、ユーザーが作成および/または認証され、ユーザー情報を取得できます。 LinuxサーバーとApacheを使用しています。私は最新のFacebookも使用していますPHP SDK v.3.1.1これがなぜ起こっているのか、そしてそれを修正する方法を誰かに教えてもらえますか?

23
Harry Andrei

先週も同様の問題があり、stateフィールドがgetLoginUrl()への複数の呼び出しによって上書きされるまで追跡されました。 getLoginUrl()を呼び出すたびに、新しいstateトークンがSDKで生成され、$_SESSION(単なるランダムな値)に格納されるため、2回呼び出すとユーザーが最初のリンクを使用してログインし、2回目の呼び出しでSDKの内部stateトークンがリセットされ、このエラーがログに記録されます。

SDKは、Facebookがユーザーを承認してサイトにリダイレクトした後に返されるURLで同じstateトークンを探し、一致しない場合はこのエラーをログに記録します(ここへのリンクは- ソース )。

36
jches

Facebook SDKコードには、同じハンドラーでトークンを2回チェックするときにバグがあります。

_facebook.php_のgetCode関数を次のように編集しました。

_protected function getCode() {
    if (!isset($_REQUEST['code']) || !isset($_REQUEST['state']) || $this->state === null) {
      return false;
    }
    if ($this->state === $_REQUEST['state']) {
        // CSRF state has done its job, so clear it
        $this->state = null;
        $this->clearPersistentData('state');
        return $_REQUEST['code'];
    }
    self::errorLog('CSRF state token does not match one provided.');

    return false;
}
_

より明確にするために、2回呼び出された場合に無効なトークンを記述しません。

明確にするために、次のような場合、同じURLハンドラーで関数を2回呼び出すことができます。

$facebook->getUser();、次に同じハンドラー$facebook->getLogoutUrl()で、getCode()が2回呼び出され、無効なエラーメッセージが表示される

8
Jimmy Kane

さて、私はこの正確な問題に一度遭遇し、URLのstatecodeパラメータに問題がありました-私の.htaccessファイルはそれらを転送していませんでした。

同じ問題が発生していると思います。

CSRF状態トークンが提供されたトークンと一致しません

お役に立てれば

3
Roni

もう1つの注意-Facebook PHP APIのドキュメントには記載されていませんが、ログインプロセスが機能するには、ApacheにPHPセッションが設定されている必要があります。これは、「CSRF状態トークンが提供されたトークンと一致しない」という問題が発生したときに発生した問題であることが判明しました。

セッション情報にmemcacheを使用するように設定されているサーバープールを使用していることを確認してください。そうでない場合、Apacheはセッション情報をローカルに書き込み、次のリクエストが同じサーバーに送信されない場合は「CSRF状態」を取得しますトークンは提供されたものと一致しません。」.

これは、開発環境(サーバーが1つの場合)では魅力的に機能したものの、本番環境では失敗したものの1つでした。

また、PHPセッションCookieを確実に通過させるために、CDN設定を再構成する必要がありました。

2
Joanne Garlow

同じ問題がありました。それは簡単です。電話しないでください

$fbLoginUrl = $facebook->getLoginUrl(...);

$fbUser = $facebook->getUser();

そうしないと、「CSRF状態トークンが指定されたものと一致しません」というエラーが発生します。

2
spurs50

チェスの答えに少し追加すると、この問題は、私がしたように、session_start()-session_write_close()関数で遊んでいる場合に発生する可能性があります。

LoginUrlをリクエストしているときに開始されたセッションがない場合、このエラーが発生します。

補足:なぜセッションを停止する必要があるのですか?

セッションを使用するスクリプトは、セッション配列が使用できるようになるのを待っているため、互いに停止します。

何千人ものユーザーがいる人気のあるアプリケーションがあり、写真を投稿するアクション(phpスクリプト)があるとします。このようなもの:

-スクリプトの先頭でセッションを開始

-Facebookに接続しています

-イメージの作成

-api呼び出しで画像を共有します。

--script終了、セッションは自動的に閉じます

これを行うと、セッションは理由もなく長時間スクリプトによって使用されます。そのようなスクリプトには注意して、代わりに次のようなものを使用してください。

-facebookオブジェクトを作成する直前にセッションを開始します

-Facebookに接続しています

--session_write_close()を使用してセッションを閉じると、セッション配列が使用可能になり、他のスクリプトでロードできます

-イメージの作成

--api呼び出しで画像を共有する/ *これはセッションを必要としないと思います。 * /

--script終了、セッションはすでに手動で閉じられています。

乾杯。

2
ZeeCoder

私のローカルマシンでも同じ問題があり、問題は私のhostsファイルがVerisignとの通信をブロックしていたため、Facebookが( http://crl.verisign.com/pca3.crl )との通信が機能しなかった(状態:404)。

私のhostsファイルからさまざまなVerisign IPアドレスをコメントアウトすることでうまくいきました!

1
Guillermo

CSRFの状態とコードはローカルセッションを使用してチェックされます。php.iniのsession.save_handlerをチェックする必要があると思います。

0
Antoine Baqain

ページで.htaccess mod rewriteリダイレクトを使用する場合は、行の最後で[QSA](クエリ文字列の追加)を使用してGET変数を保持するか、Facebookのログインに必要な$ code変数を失いました

0
askdig