Как правильно обрабатывать токен доступа и доступа к 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 пользователей теряется между этажами целевой страницы (аутентификация) -> formular -> и регистрацией. Так что я еще кое-что пропустил.

Изменить 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, чтобы узнать, не OAuthException ли где-нибудь в моем приложении 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}}); 

И эта функция вызывается в форме submit. Всегда работал на меня, но как-то он все равно отправляет форму, хотя 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; } 

Я использую теперь PHP SDK 3.x без каких-либо проблем.

Naitik автор класса удалил функцию 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); 

Мое решение

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

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

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

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

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

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

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

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

Привет, я столкнулся с той же проблемой, что я решил ее с просмотром 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;)

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