2017-02-15 66 views
9

我在多个域(不是子域)上运行Opencart v2.3.0.2多存储并希望在主站点上签出,其中包含所有商店的所有产品。多商店多域名一次结帐,单个客户登录所有商店?

由于很难在多个域上共享会话,因此认为最好在签出过程之前强制用户登录(登录凭证对所有商店和购物车项目都是相同的)。但是,默认情况下,用户必须分别登录到每个商店 - 如何为所有商店创建单个登录?登录后,我可以将它们发送到主站点进行结账。

如果您认为单一结账有更好的方法,请提出建议。

+1

这可能是有帮助的:http://stackoverflow.com/questions/5062569/how-to-do-single-sign-on-with-php – Derenir

+0

我读过大概50篇文章,其中最好的类似以上。在我发现的一个中,家伙建议在两个主站点之间进行两次重定向,并设置相同的标记。我真的希望Opencart有更好的方式,因为所有的商店都使用一个脚本来维护。也许设置一个隐藏的iframe,或从奴隶发布到主站点是更好的解决方案。也许链接本身,指向主站点结帐应该持有令牌...奖励最佳解决方案! – skobaljic

+0

是U使用 - 多个服务器与多个数据库或 - 一个服务器与多个数据库是这样的: '(1ND数据库)serve_1.com - > site_1.com ,,,,,, (第二数据库)服务器1。 com - > site_2.com。' –

回答

0

Opencart 2设置两个HTTPOnly cookie PHPSESSID默认来识别客户。因此,我决定通过商店共享/同步它们。

1。获取存储列表,以获得javascript

也许不是最好的,但在/catalog/controller/common/header.php我分配一个变量:

$this->load->language('setting/store'); 
$this->load->model('setting/store'); 
$this->load->model('setting/setting'); 

$data['multi_stores'] = array(); 

$data['multi_stores'][] = array(
    'store_id'  => 0, 
    'name'   => 'Main Site', 
    'url'   => 'https://mysite.co.uk/', 
    'is_current' => stripos('https://mysite.co.uk/', $_SERVER['SERVER_NAME']) !== false 
); 

$results = $this->model_setting_store->getStores(); 
foreach ($results as $result) { 
    $data['multi_stores'][] = array(
     'store_id'  => $result['store_id'], 
     'name'   => $result['name'], 
     'url'   => $result['url'], 
     'is_current' => stripos($result['url'], $_SERVER['SERVER_NAME']) !== false 
    ); 
} 

2比模板,我用它:

<script type="text/javascript"> 
var multiStores = <?php echo json_encode($multi_stores); ?>; 
</script> 

3.创建了两个PHP脚本来设置和获取Cookie:

  • 请注意,要设置PHP HTTPOnly cookie,第7个参数必须是true
  • 另一个需要注意的是,要获取HTTPOnly cookie,我们必须从服务器请求它,但不能通过Javascript访问它(这首先是它的目的)。

getCookies.php:

$cookies = array(
    'PHPSESSID' => $_COOKIE['PHPSESSID'], 
    'default' => $_COOKIE['default'], 
    'currency' => $_COOKIE['currency'], 
    'language' => $_COOKIE['language'] 
); 

header('Content-Type: application/json'); 
echo json_encode($cookies); 

setCookies.php:

$response = array(
    'status' => 'ok' 
); 

/* Format: [cookie name] => [expire days] */ 
$cookies_to_sync = array(
    'PHPSESSID' => '', 
    'default' => '', 
    'currency' => 30, 
    'language'=> 30 
); 

/* If no expire was set, than set session HTTPOnly cookie (last, 7th parameter 'true') */ 
foreach($cookies_to_sync as $cname=>$cexpire) { 
    if($_POST[$cname]) { 
     if($cexpire) { 
      /* 86400 seconds per day */ 
      setcookie($cname, $_POST[$cname], time() + (86400 * $cexpire), '/', null, null, false); 
     } else { 
      setcookie($cname, $_POST[$cname], null, '/', null, null, true); 
     }; 
    }; 
}; 

/* Browser requests a JSON, cross-origin enabled, with OPTIONS enabled to set cookies */ 
header('Access-Control-Allow-Origin: *'); 
header('Access-Control-Allow-Methods: POST, OPTIONS'); 
header('Access-Control-Max-Age: 1000'); 
header('Content-Type: application/json'); 
echo json_encode($response); 

4. JavaScript部分: - 请注意,为了发送/设置Cookie跨域,我们设置选项在PHP头文件和jQuery中,我们添加$.ajaxxhrFields选项withCredentials: true。有了这样的想法,我创造了我的方法来同步网站的cookie:

this.syncWebsites = function() { 
    if(typeof multiStores!='undefined') { 
     that.stores = multiStores; 
     that.synced = that.readCookie('synced'); 
     if(!that.synced) { 
      /* First get cookies */ 
      $.getJSON("catalog/view/theme/mytheme/javascript/getCookies.php", function(data) { 
       /* Send to other sites */ 
       $.each(that.stores, function(i, store) { 
        if(!store.is_current) { 
         /* Send to other sites, MUST use xhrFields->withCredentials: true, to set cookies */ 
         $.ajax({ 
          url: store.url.replace('http://', '//') + "catalog/view/theme/mytheme/javascript/setCookies.php", 
          xhrFields: { 
           withCredentials: true 
          }, 
          type: "post", 
          crossDomain: true, 
          data: data, 
          dataType: "json", 
          success:function(result){ 
           that.echo(JSON.stringify(result)); 
          }, 
          error:function(xhr, status, error){ 
           that.echo(status); 
          } 
         }); 
        }; 
       }); 
       that.createCookie('synced', 'Yes', ''); 
      }); 
     }; 
    }; 
}; 

请注意:我创建了synced的cookie,所以这要求在本届会议期间仅出现一次。

最终结果: 我们已在所有网站上同步所有Opencart 2客户。

安全考虑因素: 所有的网站都使用SSL编码。窃取信息的危险与访问所有这些网站的危险相同。

3

如果它足够让你只需登录你的用户在所有门店(和你不惯于使用相同的会话ID),你可以

1)实现的登录链接锁定为您的所有商店

2)成功登录到您的商店之一响应后把他送回其余所有门店登录链接

3)执行阿贾克斯每个登录链接。

这样的结果,你会登录到一个脱颖而出,但自动登录到所有商店

注:最好的将是,如果你的登录表单本身也将通过AJAX所以用户只需输入凭证和的情况下,成功看到更长的AJAX加载过程中,您将逐一执行剩下的登录链接

+0

我看到Opencart的设置了两个饼干** PHPSESSID **和**默认**。如果我手动将这些值复制到其他网站,比我在购物车中有相同的项目,并且我在两个网站(如果我登录)登录。也许通过AJAX发布和设置这些cookie,或者通过PHP以某种方式更好。只是争论安全问题,因为主站点使用SSL,而其他站点则不(现在)。 – skobaljic

+0

你可以通过ajax发布信息给一些PHP脚本,它会为你做些事情。同样通过https ajax请求。 – Armen

+0

我会去设置这两个具有相同值的cookie给我的所有商店,这就是Opencart需要知道的所有信息。没有必要发送登录信息,一旦Cookie相同,客户在所有网站上都是唯一的。我将使用旧JS方法在其他网站上加载1px png图像,这些图像可以工作多次。 – skobaljic

2

尝试这样

修改/system/library/session.php一些事情如下:

if ($_SERVER['HTTP_HOST'] != 'store1.loc') { 
    if (!isset($_COOKIE["PHPSESSID"]) && !isset($_GET['session_id'])) { 
     $actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";//get current URL 
     header('Location: http://store1.loc?getsession=true&url='.base64_encode($actual_link)); 
    } 
    elseif (isset($_GET['session_id'])) { //set session based on the session_id received from main store 
     session_destroy(); 
     session_id($_GET['session_id']); 
     session_start(); 
     header('Location: '. base64_decode($_GET['url'])); //redirect to original requested url 
    } 
} 
else { 
    if (isset($_GET['getsession'])) { //send back session_id 
     header('Location: http://store2.loc?session_id='.urlencode(session_id()) . '&url=' . $_GET['url']); 
    } 
} 

说明:如果用户进入不是主存储的任何存储,则重定向到主存储,如果不存在则启动会话,然后通过GET参数将会话ID发送回请求者在URL中,然后使用相同的会话ID开始会话,然后重定向回原始请求的URL。这样做的缺点是,当用户第一次访问store2时,由于重定向,页面加载将至少加倍。

+0

认为你应该引用来源? – skobaljic

+0

它适合您的状况吗? – krishna

+3

你不能只是[复制答案】(http://stackoverflow.com/questions/20252844/how-to-make-opencart-multi-store-share-same-cart-over-multiple-tlds/20290147#20290147)没有任何通知/参考。你也应该阅读[其他意见(http://stackoverflow.com/questions/42251631/multi-store-multi-domain-one-checkout-single-customer-login-into-all-stores#comment-71758996)前张贴。 – skobaljic

2

你想要的是单点登录。有很多方法可以做到这一点,更安全的方法是使用JSON Web令牌(如https://github.com/lcobucci/jwt)。简而言之,这些是已签名的JSON字符串,因此您可以使用异步加密的功能! ;)

+0

我只会在网站上同步会话cookie。不知道我是否需要这个库,认为我可以用简单的ajax来请求图像,而不是使用cookie同步。感谢您分享链接和帮助。 – skobaljic