Как правильно обрабатывать сеанс и токен доступа с помощью Facebook PHP SDK 3.0? - PullRequest
37 голосов
/ 24 июня 2011

В PHP 3.0 SDK нет 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?

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


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

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

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.ui permissions.request метода , редко пуст.

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

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

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

Ответы [ 5 ]

10 голосов
/ 27 июня 2011

Я сейчас использую PHP SDK 3.x без проблем.

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

Для токена Access это очень просто, используйте эту функцию 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);
5 голосов
/ 14 июля 2011

Мое решение

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

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

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

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

2 голосов
/ 02 июля 2011

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

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

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

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

1 голос
/ 22 августа 2011

Привет, я столкнулся с той же проблемой, кажется, я решил ее, наблюдая за API JS и перенаправляя на страницу входа 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;)

0 голосов
/ 06 августа 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...