Ответ 1
Победа моя!
Существует почти полностью недокументированная функция 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-only 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 only".
Изменить: Мое первоначальное предположение о том, что ключ "iframe only" был обновлен с помощью какого-то метода Ajax, был неправильным, оказывается, что эти значения установлены в cookie от Facebook. Это приводит к некоторым междоменным проблемам при использовании этих файлов cookie. Настройка политика файла cookie P3P позволит устранить это в большинстве браузеров, кроме Safari. Safari не работает.