サーバーのログに、「CSRF状態トークンが提供されたトークンと一致しない」というエラーが表示されます。これは、ほとんどすべてのユーザーに発生するようです。ただし、ユーザーが作成および/または認証され、ユーザー情報を取得できます。 LinuxサーバーとApacheを使用しています。私は最新のFacebookも使用していますPHP SDK v.3.1.1これがなぜ起こっているのか、そしてそれを修正する方法を誰かに教えてもらえますか?
先週も同様の問題があり、state
フィールドがgetLoginUrl()
への複数の呼び出しによって上書きされるまで追跡されました。 getLoginUrl()
を呼び出すたびに、新しいstate
トークンがSDKで生成され、$_SESSION
(単なるランダムな値)に格納されるため、2回呼び出すとユーザーが最初のリンクを使用してログインし、2回目の呼び出しでSDKの内部state
トークンがリセットされ、このエラーがログに記録されます。
SDKは、Facebookがユーザーを承認してサイトにリダイレクトした後に返されるURLで同じstate
トークンを探し、一致しない場合はこのエラーをログに記録します(ここへのリンクは- ソース )。
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回呼び出され、無効なエラーメッセージが表示される
さて、私はこの正確な問題に一度遭遇し、URLのstate
&code
パラメータに問題がありました-私の.htaccess
ファイルはそれらを転送していませんでした。
同じ問題が発生していると思います。
お役に立てれば
もう1つの注意-Facebook PHP APIのドキュメントには記載されていませんが、ログインプロセスが機能するには、ApacheにPHPセッションが設定されている必要があります。これは、「CSRF状態トークンが提供されたトークンと一致しない」という問題が発生したときに発生した問題であることが判明しました。
セッション情報にmemcacheを使用するように設定されているサーバープールを使用していることを確認してください。そうでない場合、Apacheはセッション情報をローカルに書き込み、次のリクエストが同じサーバーに送信されない場合は「CSRF状態」を取得しますトークンは提供されたものと一致しません。」.
これは、開発環境(サーバーが1つの場合)では魅力的に機能したものの、本番環境では失敗したものの1つでした。
また、PHPセッションCookieを確実に通過させるために、CDN設定を再構成する必要がありました。
同じ問題がありました。それは簡単です。電話しないでください
$fbLoginUrl = $facebook->getLoginUrl(...);
前
$fbUser = $facebook->getUser();
そうしないと、「CSRF状態トークンが指定されたものと一致しません」というエラーが発生します。
チェスの答えに少し追加すると、この問題は、私がしたように、session_start()-session_write_close()関数で遊んでいる場合に発生する可能性があります。
LoginUrlをリクエストしているときに開始されたセッションがない場合、このエラーが発生します。
補足:なぜセッションを停止する必要があるのですか?
セッションを使用するスクリプトは、セッション配列が使用できるようになるのを待っているため、互いに停止します。
何千人ものユーザーがいる人気のあるアプリケーションがあり、写真を投稿するアクション(phpスクリプト)があるとします。このようなもの:
-スクリプトの先頭でセッションを開始
-Facebookに接続しています
-イメージの作成
-api呼び出しで画像を共有します。
--script終了、セッションは自動的に閉じます
これを行うと、セッションは理由もなく長時間スクリプトによって使用されます。そのようなスクリプトには注意して、代わりに次のようなものを使用してください。
-facebookオブジェクトを作成する直前にセッションを開始します
-Facebookに接続しています
--session_write_close()を使用してセッションを閉じると、セッション配列が使用可能になり、他のスクリプトでロードできます
-イメージの作成
--api呼び出しで画像を共有する/ *これはセッションを必要としないと思います。 * /
--script終了、セッションはすでに手動で閉じられています。
乾杯。
私のローカルマシンでも同じ問題があり、問題は私のhostsファイルがVerisignとの通信をブロックしていたため、Facebookが( http://crl.verisign.com/pca3.crl )との通信が機能しなかった(状態:404)。
私のhostsファイルからさまざまなVerisign IPアドレスをコメントアウトすることでうまくいきました!
CSRFの状態とコードはローカルセッションを使用してチェックされます。php.iniのsession.save_handlerをチェックする必要があると思います。
ページで.htaccess mod rewriteリダイレクトを使用する場合は、行の最後で[QSA](クエリ文字列の追加)を使用してGET変数を保持するか、Facebookのログインに必要な$ code変数を失いました