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