我找到了解决方案。问题在于 Safari cookie 策略,用户必须更改以允许其 Safari 设置中的所有 cookie。
但我发现,如果我首先在 facebook iframe 之外重新加载页面并在那里设置会话,那么即使在 facebook iframe 内部,会话也会保持不变。
所以我创建了另一个控制器操作,只是为了启动一个新会话并将其 id 存储在会话中以供以后使用:
public function safari_session_hack()
{
$app_url = "app_url"; // the full url of your app on facebook
session_start();
$this->Session->write('Session.id', session_id());
die(header("Location:" . $app_url)); // redirect back to the FB app
}
然后在我的 FB 应用程序登录页面上,我有以下代码:
// Session fix for Safari
if (!$this->Session->read('Session.id') && strpos($_SERVER['HTTP_USER_AGENT'], 'Safari')) {
echo '<script>top.location.href="' . Router::fullbaseUrl() . Router::url(array('controller' => 'main', 'action' => 'safari_session_hack')) . '"</script>';
die;
}
它所做的只是检查会话 ID 是否未设置以及浏览器是否为 Safari。然后它重定向到 safari_session_hack() 操作,在外部页面上启动会话,将其 id 保存在会话中并重定向回页面。
现在一切正常,页面之间的会话不会丢失或破坏,因此您可以在 FB 应用程序中进行用户登录和其他需要会话数据的操作。