Обновление сеанса Facebook из приложения iframe

У меня есть приложение Facebook iframe, которое полностью внешнее. Под этим я подразумеваю, что как только пользователь получает доступ к URL-адресу холста для загрузки приложения, все ссылки в приложении iframe переходят на мои серверы, и страница холста никогда не обновляется, если только пользователь не перейдет в другое место на Facebook и не вернется (или обновляет браузер).

При начальной загрузке приложения, где Facebook создает iframe, мне передаются все обычные параметры, такие как fb_sig_user, что позволяет мне создать внутренний сеанс приложения на основе пользователя facebook. Этот сеанс приложения (который не является сеансом Facebook, это сеанс моего собственного приложения) — все, что мне нужно, чтобы позволить пользователю работать с приложением.

Проблема появляется через час. Если пользователь отходит от компьютера или использует приложение более часа, срок действия сеанса Facebook истекает. Есть некоторые страницы приложений, которые требуют получения информации о друзьях, и после истечения срока действия сеанса FB эти страницы ломаются, выдавая такие ошибки, как «Ошибка: ключ сеанса недействителен или больше не действителен».

Мой вопрос заключается в том, есть ли способ обновить сеанс пользователя Facebook из приложения iframe, чтобы он не истек через час. Делают ли это какие-либо вызовы API? Есть ли трюк Facebook Connect, чтобы что-то пропинговать? Есть ли какой-нибудь окончательный метод, чтобы сохранить его живым? Я не смог найти какие-либо примеры, специально посвященные этому.


person zombat    schedule 07.05.2009    source источник


Ответы (2)


Победа за мной!

Существует почти полностью недокументированная функция Facebook, связанная с сессиями iframe, о которой я нашел расплывчатую ссылку на в моем исследовании. Однако эта страница не очень хорошо объясняет это, и только после нескольких часов просмотра различных сеансовых ключей в моем iframe я смог понять, что происходит.

Раньше мое приложение iframe получало обычный раунд параметров fb_whatever, когда происходила начальная загрузка iframe. Итак, в моем приложении я делал это при каждом запросе:

if (isset($_REQUEST['fb_sig_session_key'])) {
    $_SESSION['fb_sig_session_key'] = $_REQUEST['fb_sig_session_key'];
}
if (! empty($_SESSION['fb_sig_session_key'])) $this->facebook->api_client->session_key = $_SESSION['fb_sig_session_key'];

Этот код получит fb_sig_session_key при начальной загрузке приложения, и я перенес его в локальный $_SESSION для использования с API. Сохранение его в локальном сеансе необходимо, потому что fb_sig_session_key никогда не передается снова, если вы не перезагрузите iframe всего приложения.

Таким образом, проблемы возникали, когда срок действия этого сеансового ключа истекал через час или около того.

Просмотрев неясную справочную страницу, я начал изучать все $_REQUEST переменных, которые я получал. Оказывается, даже по внутренней ссылке внутри вашего приложения iframe Facebook модифицирует запрос, чтобы передать некоторые параметры. По какой-то причине у них есть совершенно другой, но также действительный ключ сеанса, который приходит вместе с каждым запросом iframe!

Этот параметр назван в честь вашего API-ключа приложения Facebook. Поэтому, если ключ API вашего приложения «xyz123», каждый запрос внутри вашего iframe получает параметр с именем xyz123_session_key (а также несколько других, например xyz123_expires и xyz123_user).

После просмотра соответствующего времени истечения срока действия для основного сеанса (исходный fb_sig_session_key) и этого сеанса только для iframe (xyz123_session_key) появился свет в конце туннеля: время истечения срока действия ключа сеанса только для iframe фактически время от времени обновляется. . Я не определил, когда и как (я предполагаю, что в какой-то момент это пинг Ajax), но, тем не менее, он обновляется.

Я дождался истечения срока действия исходного сеанса fb_sig_session_key, и, конечно же, страницы моего приложения, связанные с друзьями, начали выдавать ошибки. В этот момент я переключил свой локально сохраненный ключ сеанса на новый только для iframe xyz123_session_key, и проблема была решена. Эта сессия работает так же хорошо, как и оригинал!

Итак, мое последнее исправление кода заключается в локальном хранении сеансового ключа следующим образом:

$iframeSessionKeyName = $CONFIG['facebook']['apiKey'] . '_session_key';
if (isset($_REQUEST[$iframeSessionKeyName])) {
    $_SESSION['fb_sig_session_key'] = $_REQUEST[$iframeSessionKeyName];
}
else if (isset($_REQUEST['fb_sig_session_key'])) {
    $_SESSION['fb_sig_session_key'] = $_REQUEST['fb_sig_session_key'];
}
if (! empty($_SESSION['fb_sig_session_key'])) $this->facebook->api_client->session_key = $_SESSION['fb_sig_session_key'];

Это отдает предпочтение ключу «только для iframe».

Редактировать: Мое первоначальное предположение, что ключ «только для iframe» был обновлен с помощью какого-то метода Ajax, было неверным, оказалось, что эти значения устанавливаются в файле cookie Facebook. Это приводит к некоторым междоменным проблемам при использовании этих файлов cookie. Настройка P3P политика использования файлов cookie устранит эту проблему для большинства браузеров, кроме Safari. Для Safari до сих пор нет хорошей работы.

person zombat    schedule 07.05.2009
comment
Похоже, что этот метод использует файлы cookie, поэтому у Safari возникают некоторые трудности, поскольку файлы cookie являются междоменными. - person zombat; 16.05.2009
comment
Что ж, через Ajax вы можете просто сохранить (на первой странице) и получить его из БД на всех следующих страницах - если я правильно понял ваше решение. Конечно, это должно быть сохранено с идентификатором пользователя fb в качестве ключа, но это все равно должно быть в состоянии получить или? Из-за проблемы с междоменными файлами cookie я почти все решаю с помощью базы данных и Ajax. В любом случае спасибо за ваше расследование в этом вопросе, это информация, которую я искал :-) - person SamiSalami; 30.08.2012
comment
Кажется, вы больше не сможете получить идентификатор пользователя, если срок действия сеанса истек, поэтому, возможно, вы могли бы просто использовать старомодный способ и публиковать скрытые входные данные через свое приложение... конечно, уродливое решение, но оно должно работать, и я постараюсь пойти с этим. - person SamiSalami; 30.08.2012

Просто поставь

header('P3P: CP="CAO PSA OUR"');

в верхней части вашей страницы, и вы не потеряете сеанс в iframe.

Я также заметил, что этой теме уже 2 с половиной года. Я только что наткнулся на это с помощью Google. Может мой пост поможет кому-то еще, кто столкнется с этим.

person Jan K.    schedule 28.01.2012
comment
Это решение используется только для IE, который всегда теряет сеанс FB, но это не имеет ничего общего с истечением срока действия сеанса через час - это всегда так, FB позволяет истечь. Также для решения проблемы с IE вы должны использовать этот полный заголовок: header('P3P:CP=IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT'); - person SamiSalami; 30.08.2012