Safari 第三方 Cookie iframe 技巧不再有效?

2022-08-30 04:08:16

因此,这是“我如何让第三方饼干在Safari中工作”问题的第10次报复,但我再次问,因为我认为竞争环境已经改变,也许在2012年2月之后。在Safari中获取第三方cookie的标准技巧之一如下:使用一些javascript发布到隐藏的iframe。它(曾经)欺骗Safari,让他们认为用户已经与第三方内容进行了交互,因此允许设置cookie。

我认为这个漏洞在轻微的丑闻之后已经关闭,当时有人透露谷歌正在其广告中使用这种伎俩。至少,在使用这个技巧时,我完全无法在Safari中设置cookie。我偶然发现了一些互联网帖子,声称苹果正在努力填补这个漏洞,但我没有找到任何官方消息。

作为后备,我甚至尝试重新设计主要的第三方框架,以便在内容加载之前必须单击一个按钮,但即使这种级别的直接交互也不足以融化Safari冰冷的心。

那么有没有人确切地知道Safari是否真的已经填补了这个漏洞?如果是这样,是否有其他解决方法(除了在每个请求中手动包含会话 ID)?


答案 1

只是想在这里留下一个简单的工作解决方案,不需要用户交互

正如我在一篇文章中所说:

基本上,您需要做的就是在top.location上加载您的页面,创建会话并将其重定向回Facebook。

将此代码添加到顶部并设置为应用程序最终选项卡/应用程序 URL,您将看到应用程序将毫无问题地工作。index.php$page_url

<?php
    // START SAFARI SESSION FIX
    session_start();
    $page_url = "http://www.facebook.com/pages/.../...?sk=app_...";
    if (isset($_GET["start_session"]))
        die(header("Location:" . $page_url));

    if (!isset($_GET["sid"]))
        die(header("Location:?sid=" . session_id()));
    $sid = session_id();
    if (empty($sid) || $_GET["sid"] != $sid):
?>
   <script>
        top.window.location="?start_session=true";
    </script>
<?php
    endif;
    // END SAFARI SESSION FIX
?>

注意:这是为Facebook制作的,但它实际上可以在任何其他类似情况下使用。


编辑 2012 年 12 月 20 日 - 维护已签名的请求:

上面的代码不维护请求发布数据,并且您将失去signed_request,如果您的应用程序依赖于签名请求,请随时尝试以下代码:

注意:这仍在正确测试中,并且可能不如第一个版本稳定。使用风险自负/欢迎反馈。

(感谢CBroe在这里为我指出正确的方向,从而可以改进解决方案)

// Start Session Fix
session_start();
$page_url = "http://www.facebook.com/pages/.../...?sk=app_...";
if (isset($_GET["start_session"]))
    die(header("Location:" . $page_url));
$sid = session_id();
if (!isset($_GET["sid"]))
{
    if(isset($_POST["signed_request"]))
       $_SESSION["signed_request"] = $_POST["signed_request"];
    die(header("Location:?sid=" . $sid));
}
if (empty($sid) || $_GET["sid"] != $sid)
    die('<script>top.window.location="?start_session=true";</script>');
// End Session Fix

答案 2

您说您愿意让用户在内容加载之前单击按钮。我的解决方案是让一个按钮打开一个新的浏览器窗口。该窗口为我的域设置一个 Cookie,刷新打开程序,然后关闭。

所以你的主脚本可能看起来像这样:

<?php if(count($_COOKIE) > 0): ?>
<!--Main Content Stuff-->
<?php else: ?>
<a href="/safari_cookie_fix.php" target="_blank">Click here to load content</a>
<?php endif ?>

然后safari_cookie_fix.php看起来像这样:

<?php
setcookie("safari_test", "1");
?>
<html>
    <head>
        <title>Safari Fix</title>
        <script type="text/javascript" src="/libraries/prototype.min.js"></script>
    </head>
    <body>
    <script type="text/javascript">
    document.observe('dom:loaded', function(){
        window.opener.location.reload();
        window.close();
    })
    </script>
    This window should close automatically
    </body>
</html>