我在多个域(不是子域)上运行Opencart v2.3.0.2多存储并希望在主站点上签出,其中包含所有商店的所有产品。多商店多域名一次结帐,单个客户登录所有商店?
由于很难在多个域上共享会话,因此认为最好在签出过程之前强制用户登录(登录凭证对所有商店和购物车项目都是相同的)。但是,默认情况下,用户必须分别登录到每个商店 - 如何为所有商店创建单个登录?登录后,我可以将它们发送到主站点进行结账。
如果您认为单一结账有更好的方法,请提出建议。
我在多个域(不是子域)上运行Opencart v2.3.0.2多存储并希望在主站点上签出,其中包含所有商店的所有产品。多商店多域名一次结帐,单个客户登录所有商店?
由于很难在多个域上共享会话,因此认为最好在签出过程之前强制用户登录(登录凭证对所有商店和购物车项目都是相同的)。但是,默认情况下,用户必须分别登录到每个商店 - 如何为所有商店创建单个登录?登录后,我可以将它们发送到主站点进行结账。
如果您认为单一结账有更好的方法,请提出建议。
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:
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中,我们添加$.ajax
xhrFields
选项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编码。窃取信息的危险与访问所有这些网站的危险相同。
如果它足够让你只需登录你的用户在所有门店(和你不惯于使用相同的会话ID),你可以
1)实现的登录链接锁定为您的所有商店
2)成功登录到您的商店之一响应后把他送回其余所有门店登录链接
3)执行阿贾克斯每个登录链接。
这样的结果,你会登录到一个脱颖而出,但自动登录到所有商店
注:最好的将是,如果你的登录表单本身也将通过AJAX所以用户只需输入凭证和的情况下,成功看到更长的AJAX加载过程中,您将逐一执行剩下的登录链接
我看到Opencart的设置了两个饼干** PHPSESSID **和**默认**。如果我手动将这些值复制到其他网站,比我在购物车中有相同的项目,并且我在两个网站(如果我登录)登录。也许通过AJAX发布和设置这些cookie,或者通过PHP以某种方式更好。只是争论安全问题,因为主站点使用SSL,而其他站点则不(现在)。 – skobaljic
你可以通过ajax发布信息给一些PHP脚本,它会为你做些事情。同样通过https ajax请求。 – Armen
我会去设置这两个具有相同值的cookie给我的所有商店,这就是Opencart需要知道的所有信息。没有必要发送登录信息,一旦Cookie相同,客户在所有网站上都是唯一的。我将使用旧JS方法在其他网站上加载1px png图像,这些图像可以工作多次。 – skobaljic
尝试这样
修改/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时,由于重定向,页面加载将至少加倍。
认为你应该引用来源? – skobaljic
它适合您的状况吗? – krishna
你不能只是[复制答案】(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
你想要的是单点登录。有很多方法可以做到这一点,更安全的方法是使用JSON Web令牌(如https://github.com/lcobucci/jwt)。简而言之,这些是已签名的JSON字符串,因此您可以使用异步加密的功能! ;)
我只会在网站上同步会话cookie。不知道我是否需要这个库,认为我可以用简单的ajax来请求图像,而不是使用cookie同步。感谢您分享链接和帮助。 – skobaljic
这可能是有帮助的:http://stackoverflow.com/questions/5062569/how-to-do-single-sign-on-with-php – Derenir
我读过大概50篇文章,其中最好的类似以上。在我发现的一个中,家伙建议在两个主站点之间进行两次重定向,并设置相同的标记。我真的希望Opencart有更好的方式,因为所有的商店都使用一个脚本来维护。也许设置一个隐藏的iframe,或从奴隶发布到主站点是更好的解决方案。也许链接本身,指向主站点结帐应该持有令牌...奖励最佳解决方案! – skobaljic
是U使用 - 多个服务器与多个数据库或 - 一个服务器与多个数据库是这样的: '(1ND数据库)serve_1.com - > site_1.com ,,,,,, (第二数据库)服务器1。 com - > site_2.com。' –