Мультимагазин нескольких доменов одна касса, единый вход для клиентов во все магазины?

Я работаю в многопользовательском магазине Opencart v2.3.0.2 на нескольких доменах (не поддоменах) и хочу оформить заказ на главном сайте, на котором есть все товары из всех магазинов.

Поскольку разделить сеансы в нескольких доменах сложно, подумайте, что лучше всего принудительно войти в систему пользователя до процесса оформления заказа (учетные данные для входа одинаковы для всех магазинов, и элементы корзины являются общими). Но по умолчанию пользователи должны войти в каждый магазин отдельно — Как я могу создать единый вход в / для всех магазинов? После входа в систему я могу отправить их на основной сайт для оформления заказа.

Если вы считаете, что есть лучший способ для однократной проверки, пожалуйста, предложите.

9

Решение

Если вам достаточно просто войти в систему во всех магазинах (и вы не будете использовать один и тот же идентификатор сессии), вы можете

1) реализована блокировка ссылки входа для всех ваших магазинов

2) после успешного входа в один из ваших магазинов в ответ отправьте ему все остальные ссылки входа в магазины

3) выполнить каждую ссылку для входа в систему с помощью ajax.

в результате вы войдете в систему с одного входа, но автоматически войдете во все магазины.

НОТА: Лучше всего будет, если сама форма входа будет также с помощью ajax, поэтому пользователь просто введет учетные данные и в случае успеха увидит более длительную загрузку ajax, во время которой вы будете поочередно выполнять остальные ссылки для входа в систему.

3

Другие решения

Попробуйте что-нибудь подобное

изменил /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 в URL, затем начинается сеанс используя тот же идентификатор сеанса, затем он перенаправляет обратно на исходный запрошенный URL. Недостатком этого является тот факт, что при первом посещении магазина store2 пользователь загружает страницу как минимум вдвое из-за перенаправлений.

2

То, что вы хотите, это единый вход. Есть много способов сделать это, еще один безопасный способ — использовать JSON Web Token (например, https://github.com/lcobucci/jwt). Короче говоря, это подписанные строки JSON, поэтому вы можете использовать возможности асинхронного шифрования! 😉

2

Opencart 2 устанавливает два HTTPOnly куки 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-скрипта для установки и получения куки:

  • Обратите внимание: чтобы установить PHP HTTPOnly cookie, 7-й параметр должен быть правда.
  • Еще одно замечание: чтобы получить 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 мы добавляем $.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-подписку. Опасность кражи информации такая же, как и при посещении всех этих сайтов.

0
По вопросам рекламы [email protected]