Подтвердить что ты не робот

Ток состояния CSRF не соответствует одному предоставленному FB PHP SDK 3.1.1 Oauth 2.0

В моих журналах сервера отображается "токен состояния CSRF не соответствует одной предоставленной" ошибке, которая, кажется, происходит почти для каждого пользователя. Тем не менее, пользователи создаются и/или аутентифицируются, и я могу получить информацию о пользователе. Я использую сервер Linux с Apache. Я также использую последнюю версию PHP PHP SDK v.3.1.1 Может ли кто-нибудь сказать мне, почему это происходит и как это исправить?

4b9b3361

Ответ 1

У меня была аналогичная проблема на прошлой неделе, и она была отслежена до поля state, которое было перезаписано несколькими вызовами getLoginUrl(). Каждый раз, когда вы вызываете getLoginUrl(), в SDK генерируется новый токен state и сохраняется в $_SESSION (это просто случайное значение), поэтому, если вы вызываете его дважды, и пользователь использует первую ссылку для входа в систему, второй вызов будет иметь reset внутренний тег state SDK, и вы получите эту ошибку в своих журналах.

SDK ищет тот же маркер state в URL-адресе, который возвращается после того, как Facebook разрешает пользователю и перенаправляет его обратно на ваш сайт, а если он не соответствует, он регистрирует эту ошибку (здесь ссылка на < источник href= "https://github.com/facebook/facebook-php-sdk/blob/master/src/base_facebook.php#L691" rel= "noreferrer" > .

Ответ 2

Код SDK для Facebook имеет ошибку при одновременной проверке токенов в одном и том же обработчике.

Я отредактировал функцию getCode facebook.php следующим образом:

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;
}

чтобы быть более понятным и не указывать недействительный токен, если вызывается дважды.

Чтобы быть ясным, функцию можно вызывать дважды в одном обработчике URL, если, например:

$facebook->getUser();, а затем в том же обработчике $facebook->getLogoutUrl(), тогда getCode() вызывается дважды, что приводит к неверному сообщению об ошибке

Ответ 3

Ну, однажды я столкнулся с этой точной проблемой, и у меня возникла проблема с параметрами state и code в URL-адресе - мой файл .htaccess не пересылал их.

Я предполагаю, что у вас такая же проблема.

токен состояния CSRF не соответствует указанному вами

Надеюсь, что это поможет

Ответ 4

Чтобы добавить бит в ответ chesles, эта проблема может возникнуть, если вы играете с функциями session_start() - session_write_close(), как и я.

Если начальный сеанс отсутствует, когда вы запрашиваете loginUrl, вы получите эту ошибку.

Sidenote: Зачем останавливать сеанс?

Скрипты, которые используют сеансы, останавливаются друг на друга, потому что они ждут использования массива сеансов.

Представьте, что у вас есть популярное приложение с тысячами пользователей и у вас есть действие (PHP скрипт), где вы публикуете изображение. Что-то вроде этого:

- начальный сеанс в верхней части script

- подключение к facebook

- создание изображения

- совместное использование изображения с вызовом api

- script конец, сеанс автоматически закрывается

Выполняя это, сеанс будет использоваться script в течение длительного времени без каких-либо причин. Будьте осторожны с такими сценариями, используйте что-то вроде этого:

- начальный сеанс перед тем, где вы создаете объект facebook

- подключение к facebook

- закрытие сеанса с session_write_close(), доступный массив сеансов, другие скрипты могут загружать

- создание изображения

- обмен изображением с вызовом api/* Он считает, что для этого не требуется сеанс. */

- script конец, сеанс уже закрыт вручную.

Приветствия.

Ответ 5

Еще одно примечание - хотя это не указано в документации PHP PHP API, вы должны настроить apache для сеансов PHP, чтобы процесс входа в систему работал. Это оказалось проблемой, с которой мы столкнулись, когда мы получали "токен состояния CSRF не соответствует одному предоставленному".

Убедитесь, что вы используете пул серверов, который вы настроили для использования memcache для информации о сеансе, в противном случае apache будет записывать информацию о сеансе локально, и если следующий запрос не отправится на тот же сервер, вы получите "Ток состояния CSRF не соответствует одному предоставленному".

Это была одна из тех вещей, которые работали как шарм в среде разработки (с одним сервером), но не сработали.

Нам также пришлось перенастроить наши настройки CDN, чтобы убедиться, что мы проходим через куки файлы PHP Session.

Ответ 6

У меня была такая же проблема. Это просто. Не звоните

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

до

$fbUser = $facebook->getUser();

иначе вы получите "токен состояния CSRF не соответствует одной предоставленной" ошибке.

Ответ 7

У меня была такая же проблема на моей локальной машине, и проблема оказалась в том, что мой файл hosts блокировал связь с Verisign, поэтому URL-адрес Facebook пытается связаться с (http://crl.verisign.com/pca3.crl) никогда не работал (состояние: 404).

Комментируя различные IP-адреса Verisign из моего файла hosts, этот трюк!

Ответ 8

Состояние и код CSRF проверяются с использованием локальных сеансов, я уверен, вам нужно проверить свой session.save_handler на вашем php.ini и если он работает правильно.

Ответ 9

если вы используете .htaccess mod rewrite redirects на своей странице, используйте [QSA] (Query String Append) в конце строк, чтобы сохранить переменные GET, иначе вы потеряли переменную $code, которая требуется для Вход в facebook