10

我在多个域(不是子域)上运行 Opencart v2.3.0.2 多商店,并希望在主站点上结帐,该站点包含所有商店的所有产品。

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

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

4

3 回答 3

3

如果它足以让您在所有商店中简单地登录您的用户(并且您不会使用相同的会话 ID),您可以

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

2)成功登录您的一家商店后,将所有其他商店的登录链接发回给他

3)通过ajax执行每个登录链接。

因此,您将登录到一个前台,但会自动登录到所有商店

注意:最好是您的登录表单本身也是由 ajax 提供的,因此用户只需输入凭据,如果成功,您将看到更长的 ajax 负载,在此期间您将一一执行其余登录链接

于 2017-02-18T06:15:15.757 回答
2

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

于 2017-02-23T14:06:14.150 回答
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 访问(这是它的首要目的)。

获取Cookies.php:

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

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

设置Cookies.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 标头中设置了OPTIONS$.ajax xhrFields ,对于 jQuery,我们添加了option 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', '');
            });
        };
    };
};

请注意:我创建了syncedcookie,因此此请求仅在会话期间发生一次。

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

安全注意事项: 所有网站都使用 SSL 加密。窃取信息的危险与访问所有这些网站的危险相同。

于 2017-02-24T16:29:16.673 回答