1

Facebookのサーバー側ユーザー認証を使用して、ユーザーをサイトにログインさせようとしています。CSRFを防ぐために、Facebookはランダムなセッション状態変数を作成し、それをFBに渡し、次にFBがそれを返して値を比較し、セキュリティの問題がないことを確認することをお勧めします。これは、Firefoxを除くすべてのブラウザで正常に機能するようです。Firefoxは状態変数を送信していますが、サイトに戻ったときに状態変数を保存していません。session_start()はドキュメントの上部に表示されますが、セキュリティ上の理由からいくつかの変数やその他のコードを削除したため、以下では引用されていません。

if(empty($code)) {
    $rand = md5(uniqid(rand(), TRUE)); // CSRF protection
    $_SESSION['mbny_state'] = $rand;
    $dialog_url = "https://www.facebook.com/dialog/oauth?client_id="
        . $app_id . "&redirect_uri=" . urlencode($my_url) . "&state="
        . $_SESSION['mbny_state'] . "&scope=publish_stream,user_birthday,user_hometown,email";
    header('Location: ' . $dialog_url);
}

$state = $_REQUEST['state'];
$secret_state = $_SESSION['state'];

// Check session state to prevent hacking
if($secret_state == $state) {
    $token_url = "https://graph.facebook.com/oauth/access_token?"
        . "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url)
        . "&client_secret=" . $app_secret . "&code=" . $code;

    $response = file_get_contents($token_url);
    $params = null;
    parse_str($response, $params);

    // store the access token for future requests
    $_SESSION['access_token'] = $params['access_token'];

    // define graph url allowing us to communicate with FB with user's account
    $graph_url = "https://graph.facebook.com/me?access_token="
        . $params['access_token'];

    $user = json_decode(file_get_contents($graph_url));
}
else {
    $error_message = 'An error has occurred. Your session ID does not match. Please exit and try again.<br /><br />' . $secret_state . ' :: ' . $state . ' :: ' . $_SESSION['test'];
}

Firefoxは、エラーメッセージを表示するelseに到達します。ドキュメントの後半で$_SESSION['state']の値を返しましたが、NULLになります。

さらに、テストと呼ばれるテスト変数をセッションに追加しました。これはFirefoxによって正常に保存されました。私は何が欠けていますか?

前もって感謝します。

編集: Firefoxがifステートメントの外にセッション変数を保存する用意があるように見えます。ifステートメントの前に$_SESSION['myny_state']を設定すると、FBが$codeを返したときにその値が格納されます。ここでの問題は、ifステートメントの外にあるため、ページ呼び出しごとに状態がリセットされるため、状態が完全に一致しないことです。

私たちが話すときに私は髪を失っています。

4

4 に答える 4

4

Firefox内で何が起こっているかに細心の注意を払った後、アドレスに元々「www」が含まれていたにもかかわらず、Firefoxがドメイン名から「www」を削除していることに気付きました。その後、Facebookアプリがユーザーをhttp://www.domain.com/whateverにリダイレクトしている間、セッションはhttp://domain.com/whateverに保存されていました。

これを解決するには2つの方法があります。.htaccess書き換え条件を利用してこれを修正することにしました。

RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain.com [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [L,R=301]

これは、session.cookie_domainを次のように設定することでも実現できます。

ini_set('session.cookie_domain', '.domain.com');

誰かがこれが役に立つと思うことを願っています。おそらく、実際にはバグのないものをデバッグするのに5時間節約できるでしょう。

ちなみに、ウェブサイトをwwwありまたはwwwなしのいずれか(両方ではない)で使用するように強制することは、SEOの良い習慣と考えられています。

于 2012-11-19T21:16:34.487 に答える
3

$_SESSIONvarsはクライアント側ではなく、サーバー側に保存されます。

  1. session_start()どこかに電話していますか?引用したコードに含まれていないためです。
  2. ブラウザでCookieが無効になっていますか?IIRC PHPは通常PHPSESSID、クライアントブラウザをサーバーのセッションデータに接続するためにCookieを設定します。

再編集

Facebookは、urlencodedされていないため、状態変数を削除している可能性があります。交換してみてください:

urlencode($my_url) . "&state=" . $_SESSION['state']

と:

urlencode($my_url . "&state=" . $_SESSION['state'])
于 2012-11-19T17:19:07.143 に答える
1

それが完全なコードである場合はsession_start();、セッション変数の操作を開始する直前、または上部に追加する必要があります。

session_start();また、データを追加/取得するすべてのページに追加する必要があります。

于 2012-11-19T17:18:49.000 に答える
0

Firefoxブラウザを再起動すると、問題が解決する場合があります。理由はわかりませんが、機能します。

于 2015-02-24T06:03:43.223 に答える