【问题标题】:Setting cookies from a different-domain-src iframe从不同的域 src iframe 设置 cookie
【发布时间】:2012-04-21 14:44:25
【问题描述】:

这里是有问题的页面: http://www.customazon.com/demo

主页面 (@customazon.com) 加载包含辅助域 (@gamekeg.com) 的 iframe。我想允许用户使用提供的密码登录管理控制面板。问题是,由于它是第二个域,浏览器将其视为“第三方 Cookie”,并且大多数会直接拒绝它们。我需要找到一种方法来允许在这个 iframe 中设置 cookie。要求用户调整他们的 cookie 设置不是一个选项。

我尝试过的事情:

  1. 在标头中设置 P3P 短版本(CP= 字符串的许多不同版本): header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');

  2. 使用 policy.p3p 和 p3p.xml 文件创建(可能不正确,但我已尽我所能)P3P 长版本。

  3. 一些奇怪的 javascript 加载隐藏的 iframe 并发布到它(Safari 解决方法?)。

没有任何效果。任何可以帮助找到方法来实现这一点的帮助都会很棒。

【问题讨论】:

    标签: php security iframe cookies cross-domain


    【解决方案1】:

    (我可能在这个答案中切换了域,但理论应该是一样的。)

    您最好的选择是从 gamekeg.com 登录页面向 customazon.com 发送cross-domain AJAX request(您需要发送一些特殊的标头以允许跨域请求 - 阅读该链接的更多信息)。在正常情况下,除非您控制两个站点(您似乎控制了),否则这是不可能的。

    在gamekeg.com登录页面,用户登录成功后,可以这样调用:

    // I don't expect you to use jQuery, but I don't recall the entire
    // AJAX process off of the top of my head. You may have to set
    // xhr.withCredentials = true or something.
    $.ajax(
        "http://customazon.com/ajax_login.php",
        {
            "username": <?php echo $username; ?>,
            "password_hash": <?php echo $password_hash; ?>
        }
    );
    

    ajax_login.php 可能类似于:

    // Send appropriate cross-domain headers here.
    // In addition, you must configure your crossdomain.xml in your root.
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
    header("Access-Control-Allow-Credentials: true");
    header("Access-Control-Allow-Origin: http://source.com");
    header("Access-Control-Allow-Headers: Content-Type, *");
    if (isset($_POST["username"]) && isset($_POST["password_hash"])) {
        setcookie("username", $_POST["username"], time() + 24 * 60 * 60);
        setcookie("password", $_POST["password_hash"], time() + 24 * 60 * 60);
    }
    

    然后,在框架容器上,您可以每隔一段时间检查一下用户是否已登录(readCookie 取自 QuirksMode):

    function readCookie(name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for(var i=0;i < ca.length;i++) {
                var c = ca[i];
                while (c.charAt(0)==' ') c = c.substring(1,c.length);
                if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
        }
        return null;
    }
    
    function checkAjaxLogin() {
        if (readCookie("username") !== null && readCookie("password")) {
            // You're logged in now; refreshing the page should
            // do the rest, assuming the cookies are named correctly.
            window.location.refresh();
        }
    }
    

    但是,如果您可以使用 Flash,则该过程可能会加快,因为 Flash 请求不关心跨域策略。但是,我没有使用 Flash 的技能来提供示例,无论如何,可能有很多。

    【讨论】:

    • 我已经应用了你的建议,除了 checkAjaxLogin,只是因为我不太确定它的作用或为什么它是必要的。 ajax 似乎发布正确。 ajax_login 似乎正在发挥作用。 crossdomain.xml 在那里。但是,我仍然没有看到设置任何 cookie。
    • 如果您现在尝试登录,您将在屏幕顶部看到一个 var_dump($_COOKIE)(来自 gamekeg.com)。登录后,您将看到来自 customazon 上运行的 ajax 响应的 alert()。它显示数据已收到,setcookie 已被调用,并且还打印出 $_COOKIE(来自 customazon.com)。两个 cookie var_dump 都显示空数组。我现在错过了什么?
    • 我实际上没有看到任何帧。他们应该在哪里?
    猜你喜欢
    • 2011-01-08
    • 2014-05-16
    • 1970-01-01
    • 2011-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-10
    相关资源
    最近更新 更多