Как правильно обрабатывать сеанс и токен доступа с помощью Facebook PHP SDK 3.0?


В SDK PHP 3.0 нет getSession() или какой-либо обработки сеансов вне api Facebook. Несколько дней назад разработчики facebook также каким-то образом обновили JavaScript sdk, согласно эта запись в блоге и этот отчет об ошибке.

В течение последних нескольких дней в размещенный JS SDK было внесено изменение что нарушило всю совместимость между ним и текущим PHP SDK (2.x и 3.x). Разработчики, которые использование как JS, так и PHP SDK на своих веб-сайтах, скорее всего, приведет к сбою API на стороне сервера.

Однако я не знаю, действительно ли это влияет на мою проблему. Как в ответ на этот вопрос Я извлекаю токен доступа диалогового окна OAuth с помощью PHP и сохраняю новый токен доступа в сеансе.

Текущий обходной путь

Следующий код показывает, как я обрабатываю эти сеансы. $_REQUEST['session'] - это содержание ответа OAuth диалог.

if(isset($_REQUEST['session'])) {

    $response = json_decode(stripslashes($_REQUEST['session']), true);

    if(isset($response['access_token'])) {
        $this->api->setAccessToken($response['access_token']);
        $_SESSION['access_token'] = $this->api->getAccessToken();
    }

}
elseif(isset($_SESSION['access_token']) && ! isset($_REQUEST['signed_request'])) 
    $this->api->setAccessToken($_SESSION['access_token']);
elseif(isset($_REQUEST['signed_request'])) {
    Session::invalidate('fbuser');
    $_SESSION['access_token'] = '';
}

Вот как я обрабатываю пользовательские данные:

try {
    $this->user = Session::getVar('fbuser');
    if ($this->user === false || is_null($this->user)) {
        $facebookUser = $this->api->api('me?fields=id,name,first_name,last_name');
        $this->user = new FBUserModel(array('fbId' => $facebookUser['fbId'], ...));
        Session::setVar('fbuser', $this->user);
    }
}


Проблема

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

$facebookUser = $this->api->api('me?fields=id,name,first_name,last_name');

С ошибкой:

An active access token must be used to query information about the current user.


Вопрос

Так почему же это происходит? Это очень сложно отлаживать поскольку ошибка, похоже, возникает только тогда, когда пользователь входит в приложение в первый раз, после изменения аутентификации приложения и маркера доступа. И даже это происходит не каждый раз. Как мне правильно обрабатывать сеанс и токен доступа с помощью нового PHP SDK?

Любая помощь будет высоко оценена!


Редактировать

Я обнаружил, что есть некоторые проблемы IE с файлами cookie/сеансом внутри iFrame. Как видно в этом посте в блоге. С этим намеком и некоторыми дальнейшими исследованиями я добавил следующие строки в свой загрузчик:

ini_set('session.use_trans_sid', 1);
header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');

Теперь это намного лучше, но информация примерно от 2 из 50 пользователей теряется между этапами целевой страницы (аутентификация) - >формулярный -> и регистрацией. Так что есть еще кое-что, что я упустил.


Редактировать 2

Я отредактировал свою обработку пользователей из

if ($this->user === false || is_null($this->user)) {
    // get user data
}

До

if ((is_object($this->user) && $this->user->fbId == '') || $this->user === false || is_null($this->user)) {
    // get user data
}

Кажется, это немного помогает. Я думаю, что главная проблема где-то есть на моем сеансе.

Кроме того, я добавил блок try/catch, чтобы посмотреть, не брошен ли где-нибудь в моем приложении Facebook OAuthException. Если это так, я перенаправляю верхнее местоположение на Страницу и вкладку Facebook, чтобы получить новый подписанный запрос. Хотя это может помочь решить эту проблему, я хочу, чтобы моему приложению не приходилось перенаправлять пользователя.


Редактировать 3

После нескольких дней интенсивной отладки и ведения журнала я обнаружил, что $_REQUEST['session'] грядет из FB.разрешения пользовательского интерфейса.метод запроса редко бывает пустым.

Вот как я справляюсь с этим:

Это то, что я всегда включал:

FB.provide("UIServer.Methods", {'permissions.request': {size : {width: 575, height: 300}, url: 'connect/uiserver.php', transform : FB.UIServer.genericTransform}});

И эта функция вызывается при отправке формы. Всегда работал на меня, но каким-то образом он все еще отправляет форму, хотя session == ''.

function getPermission(form) {

    session = $('#' + $(form).attr('id') + ' input[name="session"]');

    if($(session).val() != '') {
        form.submit();
        return;
    }

    FB.ui({method: "permissions.request", "perms": 'user_photos'}, function callback(info){
        if(info.status=='connected' && info.session !== null) {
            $(session).val(JSON.stringify(info.session));
            form.submit();
        }
    });
    return;
}
Author: Community, 2011-06-24

5 answers

Сейчас я использую PHP SDK 3.x без каких-либо проблем.

Наитик автор класса удалил функцию getSession(), и теперь, если вы хотите узнать, аутентифицирован пользователь или нет, используйте getUser().

Для маркера доступа это очень просто, используйте эту функцию getAccessToken(), и вы получите маркер доступа для выполнения вызовов Graph или Rest API.

$user = $facebook->getUser();

if ($user) {
//USER Logged-In
}
else {
//USER not Logged-In
}

//TO GET ACCESS TOKEN
$access_token = $facebook->getAccessToken();


//MAKE AN API CALL WITH IT
$user_info = $facebook->api('me?fields=id,name,first_name,last_name&access_token='.$access_token);
 10
Author: Hamza, 2011-07-02 16:52:38

Мое решение

Ну, поскольку все, что я делал, было просто обходным путем, пока не выйдет новый JS SDK, похоже, лучшей практики не существует. Установка session.use_trans_sid в 1 и добавление заголовка P3P помогли преодолеть проблемы с файлами cookie IFRAME IE (см. Мое Первое редактирование). После нескольких дней интенсивной отладки я обнаружил, что FB.ui permission_request не каждый раз отправляет новый токен доступа (

Если это произойдет, значит, что-то пошло не так. Но это маленькое нечто сводит меня с ума. Так как это происходит нечасто я могу перенаправлять пользователей обратно на вкладку facebook, чтобы получить новый подписанный запрос. С новым JS SDK, надеюсь, этого больше не произойдет.

Обновление: окончательное решение

Была одна маленькая вещь, которую я наблюдал, и решение можно найти здесь: Проблема FB не определена
Я не загружал JS SDK асинхронно! Это все объясняет. Иногда all.js файл загружался недостаточно быстро, поэтому произошла ошибка JS. Из-за этого, ни диалоговое окно разрешений, ни проверка JS не работали, и было отправлено пустое значение ввода #сеанса.

 5
Author: Sascha Galley, 2017-05-23 12:20:26

Для начала я бы немного отладил. Регистрируйте содержимое запросов. Что хранится в $_SESSION, что передается в $_REQUEST. Кроме того, проверьте, не связано ли это с браузером (происходит ли это независимо от браузера или есть закономерность?)

Но так как исправление проблемы с файлами cookie в IE (заголовок P3P) помогло, я предполагаю, что остались некоторые браузеры, которые запрещают сторонние файлы cookie. Насколько я знаю, некоторые версии Safari и Opera делают это по умолчанию. Кроме того, эта ошибка указывает, что не было предоставлено access_token, в отличие от недействительного или просроченного.

Вы можете проверить это, отключив сторонние файлы cookie (, например, с помощью about:config в firefox ), деавторизируя свое приложение (используя раздел "Приложения и веб-сайты" в нижней части Настроек конфиденциальности Facebook ), удалив файлы cookie (связанные с вашим URL-адресом canvas), а затем запустив приложение.

Кстати, всегда есть возможность, что facebook не вернет токен доступа, даже если он следует, как описано в ошибке 17236

 2
Author: Maciej Łebkowski, 2011-07-02 19:03:51

Привет, я столкнулся с той же проблемой, кажется, я решил ее, посмотрев JS API и перенаправив на страницу входа в PHP-SDK, если информация о пользователе читаема

Пример:

<script language="JavaScript">

function check_fb_status(){
    FB.api('/me', function(response){
     if(response.name) window.location='<?php echo $facebook->getLoginUrl(); ?>';
     else check_fb_status();
    });
}

check_fb_status();

</script>

Если скрипт прошел успешно, он загружает страницу входа, и пользователь распознается как JS, так и PHP SDK;)

 1
Author: benny, 2011-08-22 00:34:31

К вашему сведению, Facebook опубликовал обновление PHP SDK около 2 часов назад, которое добавляет поддержку нового формата файлов cookie, если вы создаете сеанс на клиенте с помощью JavaScript SDK. Обновление можно найти в репозитории Facebook PHP-SDK на GitHub.

 0
Author: Rob DiMarco, 2011-08-05 20:22:27