2017-02-15 73 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