【问题标题】:Shared Session Across Domains跨域共享会话
【发布时间】:2018-03-23 09:23:18
【问题描述】:

好的.. 我有两个域 example.com 和 example.net,它们共享相同的代码空间和会话。问题是当用户改变语言时域应该改变,当这种情况发生时,所有的会话数据都会丢失。我想在此之前进行 ajax 调用,以便更改会话。 这是用于初始化会话的代码。

<?php 
    /* This method is invoked */
    public function start($session_id = '', $key = 'default') {
        if (!session_id()) {
            ini_set('session.use_only_cookies', 'Off');
            ini_set('session.use_cookies', 'On');
            ini_set('session.use_trans_sid', 'Off');
            ini_set('session.cookie_httponly', 'On');

            if ($session_id) {
                session_id($session_id);
            }   

            if (isset($_COOKIE[session_name()]) && !preg_match('/^[a-zA-Z0-9,\-]{22,52}$/', $_COOKIE[session_name()])) {
                exit('Error: Invalid session ID!');
            }

            session_set_cookie_params(0, '/');
            session_start();
        }

        if (!isset($_SESSION[$key])) {
            $_SESSION[$key] = array();
        }

        $this->data =& $_SESSION[$key]; 

        return true;            
    }

我尝试创建一个独立的脚本来处理 ajax 调用,但它失败了。

<?php 
    ini_set('session.use_only_cookies', 'Off');
    ini_set('session.use_cookies', 'On');
    ini_set('session.use_trans_sid', 'Off');
    ini_set('session.cookie_httponly', 'On');


    session_set_cookie_params(0, '/');
    session_start();
    session_id($_POST['session_id']);


    header('Content-Type: application/json');
    $data = array('session_id' => session_id());
    echo json_encode($data);

在两个域之间切换时不会保留会话。 有什么线索吗?

【问题讨论】:

  • 域都是同一个域的子域吗?将包含域放入session_set_cookie_params() 调用中。
  • 禁用session.use_only_cookies 很危险!
  • @Barmar 不,它们不是子域。它们是 2 个不同的域 - example.com 和 example.net。
  • 那你可能搞砸了。 Cookie 不能在不同域之间共享。你真的要使用不同的域,你不能从example.fr重定向到fr.example.com吗?
  • 不,我不能使用子域。

标签: php session session-variables session-cookies


【解决方案1】:

这是网络浏览器的一项安全功能 - 会话使用附加到域的 cookie,浏览器不会将此 cookie 发送到另一个域。

当您控制这两个域时,您可以通过在 URL 中包含身份验证信息来实现这一点。这是一个复杂的话题。您可以自制一些可行的方法,但如果您不熟悉安全问题,最好使用现成的单点登录解决方案。

【讨论】:

  • 虽然我完全同意您的回答,尤其是 SSO 的部分 - 遗憾的是,没有 SSO 解决方案是......实际上很好、简单且开箱即用。我希望有,但是 SimpleSamlPHP - 超级垃圾,应该用火和酸烧掉。 Auth0、PingIdentity、Okta——既不容易,也不免费。有用于创建您自己的解决方案 (LightSaml) 的库,但所有这些都意味着开发人员了解 SSO 协议。在这种特殊情况下,在域之间共享 cookie 可能更容易。这不是最优雅的解决方案。但我们不是在这里谈论企业应用程序。
  • @N.B.从概念上讲当然更容易,但它取决于可靠性 - 你需要每个人的浏览器都可以玩我会在 URL 中使用自定义身份验证令牌,但这是一篇博客文章,而不是 SO 答案。
  • 所以我绝对没有办法将 session_id 发送到另一个域并在那里劫持会话?
  • @nikksan 没错。您需要通过在 URL 中传递的令牌查看 SSO 或自行滚动。关于拥有单独的域可能值得争论。
  • @SimonBrahan 在我们的应用程序中,我们不需要用户登录才能使用它,这消除了 SSO 作为可能的解决方案。
猜你喜欢
  • 1970-01-01
  • 2011-02-26
  • 1970-01-01
  • 1970-01-01
  • 2012-10-05
  • 2016-08-01
  • 2021-01-25
  • 2011-06-11
  • 1970-01-01
相关资源
最近更新 更多