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