多店多域一次结账,单个客户登录到所有商店?
Multi store multi domain one checkout, single customer login into all stores?
我是 运行 Opencart v2.3.0.2 在多个域(不是子域)上的多商店,想在主站点上结帐,该站点包含所有商店的所有产品。
由于很难在多个域上共享会话,因此认为最好在结帐过程之前强制用户登录(所有商店的登录凭据都相同,并且购物车项目是共享的)。但是,默认情况下,用户必须分别登录每个商店 - 如何创建单一登录 into/for 所有商店 ?登录后,我可以将它们发送到主站点进行结帐。
如果您认为有更好的单点结账方式,欢迎提出。
如果您只需在所有商店中登录您的用户就足够了(并且您不会使用相同的会话 ID),您可以
1) 为所有商店实施登录 link 锁定
2) 成功登录到您的一家商店后作为回应将他发回所有其他商店登录 links
3) 执行每个登录 link by ajax.
因此您将登录一个,但会自动登录所有商店
注意: 最好是您的登录表单本身也由 ajax 填写,这样用户只需输入凭据,如果成功,会看到更长的时间 ajax加载期间你将一一执行rest login links
您想要的是单点登录。有很多方法可以做到这一点,一种更安全的方法是使用 JSON Web Token(如 https://github.com/lcobucci/jwt)。简而言之,这些是带符号的 JSON 字符串,因此您可以使用异步加密的强大功能! ;)
Opencart 2 设置了两个 HTTPOnly cookie PHPSESSID 和 default 来识别客户。因此,我决定 share/sync 他们在商店里。
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部分:
- 请注意,为了 send/set cookies cross-domain,我们在 PHP header 和 jQuery 中设置了 OPTIONS我们添加 $.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,因此此请求仅在 session 期间发生一次。
最终结果:
我们在所有网站上同步了所有 Opencart 2 客户。
安全考虑:
所有网站都使用 SSL 加密。窃取信息的危险与访问所有这些网站的危险相同。
我是 运行 Opencart v2.3.0.2 在多个域(不是子域)上的多商店,想在主站点上结帐,该站点包含所有商店的所有产品。
由于很难在多个域上共享会话,因此认为最好在结帐过程之前强制用户登录(所有商店的登录凭据都相同,并且购物车项目是共享的)。但是,默认情况下,用户必须分别登录每个商店 - 如何创建单一登录 into/for 所有商店 ?登录后,我可以将它们发送到主站点进行结帐。
如果您认为有更好的单点结账方式,欢迎提出。
如果您只需在所有商店中登录您的用户就足够了(并且您不会使用相同的会话 ID),您可以
1) 为所有商店实施登录 link 锁定
2) 成功登录到您的一家商店后作为回应将他发回所有其他商店登录 links
3) 执行每个登录 link by ajax.
因此您将登录一个,但会自动登录所有商店
注意: 最好是您的登录表单本身也由 ajax 填写,这样用户只需输入凭据,如果成功,会看到更长的时间 ajax加载期间你将一一执行rest login links
您想要的是单点登录。有很多方法可以做到这一点,一种更安全的方法是使用 JSON Web Token(如 https://github.com/lcobucci/jwt)。简而言之,这些是带符号的 JSON 字符串,因此您可以使用异步加密的强大功能! ;)
Opencart 2 设置了两个 HTTPOnly cookie PHPSESSID 和 default 来识别客户。因此,我决定 share/sync 他们在商店里。
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部分:
- 请注意,为了 send/set cookies cross-domain,我们在 PHP header 和 jQuery 中设置了 OPTIONS我们添加 $.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,因此此请求仅在 session 期间发生一次。
最终结果: 我们在所有网站上同步了所有 Opencart 2 客户。
安全考虑: 所有网站都使用 SSL 加密。窃取信息的危险与访问所有这些网站的危险相同。