跨域会话 - 共享购物车跨域

时间:2010-06-02 08:56:55

标签: php session cookies cross-domain client-side

我们用eshop(php,mysql)解决了这个问题。客户希望在具有共享购物车的两个域上拥有相同的电子商店。在商店中,顾客可以在没有用户帐户的情况下进行购物(无法登录)。并且存在问题,如何使共享购物车跨域。

购物车中的数据存储在会话中,我们也存储在数据库中。但我们无法解决在域上传输数据的问题。识别未记录的用户不是防洞的(research)。

示例,它应该如何工作

客户转到domainOne并向购物车添加一些内容。然后他去domainTwo(通过链接,输入域名地址,然而)并添加一些其他的东西到购物车。在购物车中,他有来自两个域的东西(刷新页面后)。

你有什么想法,如何解决这个问题?

什么行不通:

  • 由于客户需求而无法重定向
  • Cookie与域
  • 相关
  • set_cookie与其他域无法正常工作
  • 最简单的方法是仅继承sessionid(存储在cookie中),但我们不知道如何全面识别未记录的用户。
  • 还有其他地方,除了cookie之外,数据可以存储在客户端吗? (可能不是)
  • 我们不能使用url中的params发送sessionid(如果用户点击链接到其他域)或解析标题引用,bcs我们不知道,用户如何实现其他域。

如果你无法理解我,请带我一个问题。如果您认为,在共享(普通)购物车的两个域上使用eshop是个坏主意,请不要告诉我,我们知道。

感谢您的回答。

11 个答案:

答案 0 :(得分:9)

您可以使用第三个域来识别所有域中的客户。

例如,使用http://thirdDomain.com/session.php上的PHP文件,该文件包含在两个商店的所有页面上。

样品:

<script type="text/javascript" src="http://thirdDomain.com/session.php"></script>

在您的客户切换域名后,您可以使用第三个域名将他识别为同一客户。

您可以将两个商店的会话ID分配到第三个域的会话ID,以访问两个商店的购物车。您只需要通知第三个域您的商店会话(即将它们添加为参数)。

根据您对代码和模板的灵活程度,您甚至可以使用第三个域中的输出来定义商店中的会话ID。这样,您可以在所有域上使用相同的会话ID。 但通常会话ID分配应该是更安全的方式。

使用javascript版本,您还可以输出脚本,这些脚本可以将会话ID添加到当前html页面中的所有外向链接和表单到另一个域。如果您可以将您的客户识别为阻止Cookie,则可能会感兴趣。 您还可以使用javascript通知父文档有关现有会话的信息。

答案 1 :(得分:4)

这一直在被问到。

搜索SSO。

您需要在域中传递URL(或通过POST)中的会话ID,然后:

1)检查目标域上尚不存在会话

2)使用发送的会话ID重新绑定会话

e.g。

if ((!$_COOKIE[session_name()]) && $_GET['passed_id']) {
    if (check_session_exists($_GET['passed_id'])) { 
        session_id($_GET['passed_id']);
    }
}
session_start();
...
function check_session_exists($id)
{
   $path=session_save_path() . $id;
   if (file_exists($path) && (time()-filemtime($path)<session_cache_expire())) {
      return true;
   }
   return false;
}

这也意味着你需要添加'?passed_id ='。 urlencode(session_id())指向指向其他域的任何URL。

下进行。

答案 2 :(得分:3)

架构非常简单且使用广泛。谷歌为它提供众多服务。通过跟踪浏览器和各种谷歌服务之间的HTTP交换,您可以全面了解这一想法。

假设我们的客户已获得第一个域名的授权。通过到达第二个,我们必须:

  1. 启动会话并在其中存储一些令牌。
  2. 要求浏览器以某种方式请求第一个域名并发送此令牌。
  3. 第一个域将识别我们的客户端,并在此令牌和用户ID之间的共享数据库中建立连接。
  4. 通过再次请求第二个域名,我们将授权它已经启动会话。
  5. 唯一的问题是如何申请第一个域名。它可以是图片,JS请求或整个页面重定向。某些选择取决于你。

答案 3 :(得分:1)

我认为你可以使用Flash LSO来解决这个问题。通常,LSO存储在其特定于域的沙箱中,但如果两个域对象允许,则可以按照http://download.macromedia.com/pub/flash/whitepapers/security.pdf中的“跨电影通信”部分中的说明进行通信。 有关LSO的一般信息: http://www.adobe.com/products/flashplayer/articles/lso/

答案 4 :(得分:0)

SSO。

CartA有iframe,1)检查用户是否“有效”(有会话)2)创建anon会话 CartB有iframe做1)或2)

iframe从SSO域(您可以拥有的任何域)加载

SSO解决方案:构建您的或使用其他人 - 比如simplesamlphp或其他东西......

并且不需要使用URI传递会话/参数...

答案 5 :(得分:0)

您可以将数据存储在除Cookie之外的其他位置(例如Flash Cookie,localStorage),但都使用相同的源策略,这是Web的标准安全模型:域存储的数据只能通过该域及其子域。标准解决方法是将外部域中的iframe嵌入到页面中。 iframe可以访问外域的cookie,其URL将由本地域控制,允许通信。

基于此的简单解决方案是拥有(domainA sessionid,domainB sessionid)对的表。当新用户到达domainA时,(new sessionid,NULL)被添加到表中;显示给他的页面包含一个不可见的iframe,其中source = http://domainB/mergeSessions.php?sessionA=1234。 mergeSessions.php然后将sessionA作为URL参数接收,sessionB作为cookie接收,并相应地更新会话链接表。

答案 6 :(得分:0)

您可以尝试通过IP,浏览器类型,浏览器版本,操作系统,屏幕分辨率以及您提出的任何其他内容来识别您的访问者。当有人访问任一站点时,您将存储在共享数据库中。

如果在一个小时间窗口内,说&lt; 5分钟,来自该IP的请求带有这些参数,您可以合理地假设它是同一个用户。同样,请确保您使用您能找到的所有内容来识别该用户,并且绝不会确定任何安全的内容,否则您将受到劫持。

答案 7 :(得分:0)

这样的事情怎么样,不确定它会有多好。

用户转到store1。如果用户没有会话cookie,请重定向到store2上的特殊页面,询问会话ID并发送store1上的url返回。特殊页面查看会话cookie并使用会话ID重定向回store1上的原始URL(如@symcbean的答案)。然后在store1上,会话cookie被设置(或创建为新的)并且不再发生重定向。如果用户在store2上没有会话cookie,则相同但相反。

但如果用户没有启用cookie,我会看到无限循环发生。不确定是否有可能以某种方式检测和停止。

但这种方式充其量只是hacky。

答案 8 :(得分:0)

1)显然,对两个域使用相同的会话存储(文件,数据库,memcached,通常的嫌疑人。) 2)如果在session_start()之后$ _SESSION为空,则在会话中创建一个“所有域”数组(在每个域上执行此操作,无论它是哪一个,)。

$_SESSION['all_domains'] = array(
    'domain1.com'  => true, //<= current domain the customer is on,
    'domain2.com'  => false, //other domain, no cookie for it yet.
    'domain2.com'  => false); //repeat for all domains needed

3)在所有域上创建会话设置器脚本(让我们称之为'sesset.php':

 <?php
     if(isset($_GET['sessid']){
          session_id($_GET['sessid']);
          session_start();
          //also, check here for the domains:
          if(!isset($_SESSION['all_domains'])){
              //set the array as before, flag this domain as true.
          } else {
              $_SESSION['all_domains'][$_SERVER['HTTP_HOST']] = true;
              //you might want to set a custom domainname instead of HTTP_HOST, so you won't get doubles from domain with & without www. and so on.
          }
     }
 ?>

4)在每个可以想象的php HTML页面上,将它放在身体末端附近:

 <?php
     foreach($_SESSION['all_domains'] as $domain => $domainset){
         if(!$domainset){
             echo '<img src="http://'.$domain.'/sesset.php?sessid='.session_id().' width="1" height="1"/>';
         }
     }
 ?>

不完全,但会得到几乎所有用户。当然,人们可以通过重定向级联而不是“隐藏图像”来做到这一点,但搜索机器人(google等人)非常对此感到困惑,特别是如果他们不记得cookie并且再次被重定向并且被重新定向。试。

答案 9 :(得分:0)

easyXDM是一个框架,允许用户轻松解决同源策略。 它的内置RPC功能非常易于使用,您应该在没有时间运行。

对于您的情况,选择其中一个域作为“结帐”域(A) - 这是将保存会话的域。在同一个域上,您创建一个带有easyXDM端点的小文件,该端点负责存储/检索从其他域(B)发送的数据。

现在,在域B中,您包含easyXDM,在存储/检索购物车中的数据时,您可以访问RPC方法。

答案 10 :(得分:0)

选项1使用iframe:

  • 网站1有一个网站2的iframe
  • 网站2有一个网站1的iframe

当用户从网站1中选择某个项目时,请将iframe值设置为动态字符串,即domain2.com/iframe.php?itemid=someitem。

让domain2从iframe中使用PHP获取$ _GET信息并更新用户的cookie。

在另一个方向做同样的事。

选项2:Javascript包含

您可以使用PHP生成的跨站点包含的JS文件执行类似操作,以将用户cookie的内容“拉”到其他站点。

选项3:卷曲

只需将数据从一个域发布到另一个域,因此两者都有一个副本。这是最安全的方法,因为无法保证不能复制IP地址或其他标识数据。虽然,你可以有一些“问题”或密码,以确保它是同一个人。可能通过设置电子邮件地址?

选项4:第三方Cookie

我认为已经提到过这个,但是您可以从第三个域设置cookie,因此两个站点在功能上完全相同,而不是在两者之间来回切换。