Почему getSessionFromRedirect() возвращает NULL?

У меня есть следующий код, который перенаправляет пользователя на вход в facebook и пытается извлечь сеанс, но сеанс NULL:

<?php

session_start();

require 'vendor/autoload.php';

use Facebook\FacebookSession;
use Facebook\FacebookRedirectLoginHelper;

FacebookSession::setDefaultApplication('Foo', 'Bar');

$helper = new FacebookRedirectLoginHelper('Baz');
$loginUrl = $helper->getLoginUrl();  

echo '<a href="' . $loginUrl . '">Log In</a>';  

$session = $helper->getSessionFromRedirect();  

// This displays [NULL] always
echo '[' . gettype($session) . ']';

?>

Я не понимаю, почему $session всегда имеет значение NULL. Пожалуйста, помогите.

Ответы

Ответ 1

Это происходит из-за функции getLoginUrl(),

потому что, когда мы упомянули ту же страницу, что и страница перенаправления FB, она вызывает функцию getLoginUrl() снова и снова.., которая меняет значение $this->state variable

а затем isValidRedirect() и getSessionFromRedirect() всегда возвращают null

Вот решение использовать ту же страницу, что и страница перенаправления FB:

Не вызывайте getLoginUrl(), когда facebook перенаправляет вас на ту же страницу, просто добавьте правильную проверку сеанса, чтобы проверить действительный сеанс facebook (см. следующий пример кода).

session_start();
require("facebook/autoload.php");


use Facebook\FacebookSession;
use Facebook\FacebookRedirectLoginHelper;
use Facebook\GraphUser;
use Facebook\FacebookRequestException;

FacebookSession::setDefaultApplication('appid84', '0secret0a626c6');

$helper = new FacebookRedirectLoginHelper('http://tmd.local/fblogin.php');

try {
  $session = $helper->getSessionFromRedirect();
  // var_dump($session);
} catch(FacebookRequestException $ex) {
} catch(\Exception $ex) {
}
if ($session) {
  var_dump($session);
}
else
{
  $loginUrl = $helper->getLoginUrl();
  header("location:".$loginUrl);
  exit;
}

Ответ 2

Вы должны называть getSessionFromRedirect только на странице Facebook перенаправляет пользователя после входа в систему. Затем сохраните этот сеанс где-нибудь, например $_SESSION, и повторно используйте его в другом месте.

Проблема заключается в том, что когда вы снова создаете URL-адрес входа, он изменяет переменную 'state', используемую для защиты от CSRF.

Ответ 3

Итак, целью было получить FacebookSession. Для отображения ссылки "Вход" должно быть 2 страницы: 1, а другой - для экземпляра FacebookSession. В файле page1.php:

<?php

session_start();

require 'vendor/autoload.php';

use Facebook\FacebookSession;
use Facebook\FacebookRedirectLoginHelper;

FacebookSession::setDefaultApplication('foo', 'bar');

$helper = new FacebookRedirectLoginHelper('page2.php');
$loginUrl = $helper->getLoginUrl();

echo '<a href="' . $loginUrl . '">Log In</a>';

?>

В page2.php put:

<?php

session_start();

require 'vendor/autoload.php';

use Facebook\FacebookSession;
use Facebook\FacebookRedirectLoginHelper;

FacebookSession::setDefaultApplication('foo', 'bar');

$helper = new FacebookRedirectLoginHelper('page2.php');

// Now you have the session
$session = $helper->getSessionFromRedirect();
?>

Спасибо Fosco за вашу помощь.

Ответ 5

У меня была та же проблема, что и все вышеперечисленное, и я исправил ее

Изменение настройки приложения. Разработчики Facebook → Мое приложение → Настройки → Дополнительно → Действительные URI перенаправления OAuth → Добавить '/' в конце каталога. Если это файл, то закончите путь в каталоге, в котором находится файл.

Ответ 7

В строке 214 FacebookRedirectLoginHelper.php есть ошибка:

измените $_GET ['state'] на $_SESSION ['state'] следующим образом:

  /**
   * Check if a redirect has a valid state.
   *
   * @return bool
   */
  protected function isValidRedirect()
  {
    $savedState = $this->loadState();
    if (!$this->getCode() || !isset($_GET['state'])) {
      return false;
    }
    $givenState = $_GET['state'];
    $savedLen = mb_strlen($savedState);
    $givenLen = mb_strlen($givenState);
    if ($savedLen !== $givenLen) {
      return false;
    }
    $result = 0;
    for ($i = 0; $i < $savedLen; $i++) {
      $result |= ord($savedState[$i]) ^ ord($givenState[$i]);
    }
    return $result === 0;
  }

:

 /**
   * Check if a redirect has a valid state.
   *
   * @return bool
   */
  protected function isValidRedirect()
  {
    $savedState = $this->loadState();
    if (!$this->getCode() || !isset($_SESSION['state'])) {
      return false;
    }
    $givenState = $_SESSION['state'];
    $savedLen = mb_strlen($savedState);
    $givenLen = mb_strlen($givenState);
    if ($savedLen !== $givenLen) {
      return false;
    }
    $result = 0;
    for ($i = 0; $i < $savedLen; $i++) {
      $result |= ord($savedState[$i]) ^ ord($givenState[$i]);
    }
    return $result === 0;
  }

Ответ 8

То, что имело для меня реальное значение, было адресом перенаправления Url, который я использовал. Часы и часы из-за косой черты.

Объяснение примерами:

(Неправильный)

$helper = new FacebookRedirectLoginHelper('http://www.example.com');

(справа)

$helper = new FacebookRedirectLoginHelper('http://www.example.com/');

Я прочитал тонну учебников и ответов на Stackoverflow, и этот последний слэш стал настоящим ответом. Я надеюсь, что это поможет кому-то