Я использую аутентификацию пользователя на стороне сервера 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 делает это другим, отображающим сообщение об ошибке. Я вернул значение $ _SESSION ['state'] позже в документе, и оно приближается к NULL.
Кроме того, я добавил тестовую переменную для сессии, называемую тестом, и она была хорошо сохранена Firefox. Что мне не хватает?
Заранее спасибо.
Изменить: похоже, Firefox готов хранить переменные сеанса вне инструкции if. Если я устанавливаю $ _SESSION ['myny_state'] перед оператором if, он сохраняет это значение, когда FB возвращается с кодом $. Проблема здесь в том, что состояние определенно не соответствует, потому что оно сбрасывается при каждом вызове страницы, когда он находится вне оператора if.
Я теряю волосы, когда мы говорим.
После некоторого пристального внимания к тому, что происходило в Firefox, я заметил, что Firefox лишил «www» из доменного имени, даже если адрес первоначально включал «www». Затем сеанс был сохранен в http://domain.com/whatever, в то время как приложение Facebook перенаправляло пользователя обратно на http://www.domain.com/whatever .
Это можно решить двумя способами. Я решил исправить это, используя условие перезаписи .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');
Надеюсь, кто-то найдет это полезным. Возможно, это избавит вас от пяти часов отладки чего-то, что на самом деле является ошибкой.
В качестве побочного примечания считается хорошей практикой SEO, чтобы заставить ваш сайт использовать либо с www, либо без www – не оба.
$_SESSION
vars хранятся на стороне сервера, а не на стороне клиента.
session_start()
где-нибудь? Потому что это не в коде, который вы цитировали. PHPSESSID
для подключения браузера клиента к данным сеанса сервера. Facebook может удалить свою переменную состояния, поскольку она не указана. Попробуйте заменить:
urlencode($my_url) . "&state=" . $_SESSION['state']
с:
urlencode($my_url . "&state=" . $_SESSION['state'])
Если это ваш полный код, вам нужно добавить session_start();
вверху или перед тем, как вы начнете работать с сеансами.
Кроме того, вам нужно добавить session_start();
на всех страницах, которые вы хотите добавить / получить данные.
Иногда перезагрузка браузера Firefox может решить проблему. Я не знаю почему, но это работает.