跨不同域保留会话变量


Preserving session variables across different domains

我不确定这是否可能。

我公司的主站点接受信用卡和其他付款信息。他们还有其他与我们举办的活动直接相关的网站。例如,我们的主站点是这样的:

http://www.etm124biz.com

但是有另一个专门用于年度活动的网站:

http://www.etm124annualgala.com

我的"活动"网站正在处理注册并保存到我们的数据库中,但我们的主网站处理信用卡处理。在主网站上处理当前购买时,会话用于将数据传递到付款/抄送屏幕。

无需更改我的付款代码(例如接受 $_GET 参数),我的 $_SESSION 变量不应该被传递吗?

例:

$_SESSION['s_address1'] = $_POST['address1'];
$_SESSION['s_address2'] = $_POST['address2'];
$_SESSION['s_city']     = $_POST['city'];
$_SESSION['s_state']    = $_POST['state'];
$_SESSION['s_zip']      = $_POST['zip'];
header('Location: https://www.etm124biz.com/payment.php?oid=' . $oid . '&src=conf&id=' . $seq);

我的payment.php页面查找上面的地址会话变量。

跨域会话 ID

默认情况下,会话 ID 使用 Cookie 进行传递。由于您的网站位于不同的域中,因此会话cookie不会转移,因此这是阻止跨域会话工作的一件事。

传输会话 id 的一种技术是将它们附加到所有请求的查询字符串中(PHP 甚至对此有一定程度的内置支持)。但是,这种做事方式有很多缺点 - 最重要的是人们一直在复制/粘贴URL,这意味着显示有效和重用无效的会话ID - 因此不建议这样做

更好的方法是使用 Javascript 在所有感兴趣的域中发出跨域请求(当然,这需要在这方面进行合作)。这样,您可以根据需要在任意数量的服务器上无缝传输会话 ID。

共享会话数据

即使 cookie 不是问题,您也需要将会话数据保存在所有服务器通常可以访问的某些存储上。默认存储是本地文件系统,因此,如果您需要跨域会话,则需要更改此设置。

此问题的简单解决方案是使用自定义会话处理程序,该处理程序将数据存储在数据库或其他全局可访问的存储中。

回答这个问题已经很晚了,但是由于我遇到了这个问题,即使在数十个小时并搜索Google之后也无法找到解决方案,堆栈溢出到处都是,但没有成功。但是现在我终于弄清楚了问题和解决方案。

服务器端

对于跨域 PHP 会话,我们需要执行以下操作

步骤 1

首先,我们需要在 php 接收请求的主域中.htAccess设置这些行

SetEnvIf Origin ^(http?://m'.example'.com(?::'d{1,5})?)$   CORS_ALLOW_ORIGIN=$1
Header append Access-Control-Allow-Origin  %{CORS_ALLOW_ORIGIN}e   env=CORS_ALLOW_ORIGIN
Header set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header set Access-Control-Allow-Credentials true
Header set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"

上面的这些行告诉仅允许来自 http://m.example.com 的请求。请注意,我已经设置了http.如果您有 SSL 连接,则可以设置https

步骤 2

您必须允许 PHP 为不同的子域共享相同的会话,然后才能session_start()

ini_set('session.cookie_domain', '.example.com');
session_start();

如果您有权访问php.ini然后设置它,那么您无需在 PHP 文件中设置上述行。

客户端

最后,您必须告诉浏览器使用 Cross-Domain 发出请求。如在 JQuery 中

$(document).ready(function()
{
  $.ajaxSetup({
    crossDomain: true,
    xhrFields: {
        withCredentials: true
    }
  });
});

这个问题确实探讨了很多这个问题。

  • 如何创建跨多个域的共享登录服务?

假设您在一台计算机上将两个域作为虚拟服务器,并且您没有调用 session_save_path()(或者您在两台服务器上使用相同的目录调用它),您可以使用 session_id('..');

例如,如果您有 2 个域,origin1.localhost 和 origin2.localhost:

$set = null;
if(isset($_GET['sharesession'])) {
        $set = session_id($_GET['sharesession']); //call before session_start()
}
session_start();
var_dump(session_id()); //show current session id
var_dumP($_COOKIE); // cookie send by browser, changes after second reload
var_dump($_SESSION); //filled after second reload as its values are assigned in the code below
if($_SERVER['HTTP_HOST'] === 'origin1.localhost') {
    $_SESSION['origin1'] = true;
} else {
   $_SESSION['origin2'] = true;
}

echo '<a href="http://origin1.localhost?sharesession='.session_id().'">origin1.localhost</a><br />';
echo '<a href="http://origin2.localhost?sharesession='.session_id().'">origin2.localhost</a>';

当然,您不必只使用 GET 并且还必须使用 POST 或 Javascript 跨域请求来发送会话 ID。