Multipass登錄適用于同時擁有獨(dú)立網(wǎng)站和SHOPLINE商店的店主。該功能允許用戶從網(wǎng)站重定向到SHOPLINE商店,并使用他們在原始網(wǎng)站注冊時使用的相同電子郵件地址進(jìn)行無縫登錄。如果用戶在商店中沒有帳戶,系統(tǒng)將會根據(jù)其電子郵件地址自動創(chuàng)建一個新賬戶。
一、如何使用Multipass
在 SHOPLINE 中啟用 Multipass 登錄。
在 SHOPLINE admin 中,點(diǎn)擊【設(shè)置】>【客戶賬戶】>【客戶賬戶類型】。請先確保已選擇【經(jīng)典客戶賬戶】。然后,找到【通過 Multipass 登錄】,點(diǎn)擊【啟用】;
啟用后,將與共享一個【加密密鑰】。需要此密鑰才能生成令牌,用于允許客戶登錄店鋪。為避免安全隱患,請確保密鑰保密。
1、使用 JSON 對客戶信息進(jìn)行編碼
客戶信息表示為哈希,該哈希必須至少包含客戶的電子郵件地址和當(dāng)前時間戳(ISO8601 編碼)。還可以附上客戶的名字、姓氏或多個送貨地址?;蛘撸梢园蛻舢?dāng)前瀏覽器會話的 IP 地址,使令牌僅適用于來自此 IP 地址的請求。
包含所有必填字段的最小示例可能如下所示:
{ "email": "peter@shopline.com", "created_at": "2013-04-11T15:16:23-04:00", }
包含一些可選字段的示例可能如下所示:
{ "email": "peter@shopline.com", "created_at": "2013-04-11T15:16:23-04:00", "first_name": "Peter", "last_name": "jason", "tag_string": "canadian, premium", "identifier": "peter123", "remote_ip": "107.20.160.121", "return_to": "http://yourstore.com/some_specific_site", "addresses": [ { "address1": "123 Oak St", "city": "Ottawa", "country": "Canada", "first_name": "Peter", "last_name": "Jason", "phone": "555-1212", "province": "Ontario", "zip": "123 ABC", "province_code": "ON", "country_code": "CA", "default": true } ] }
可以通過將“tag_string”設(shè)置為逗號分隔的單字值列表來將標(biāo)簽歸因于客戶。這些標(biāo)簽將覆蓋可能已經(jīng)歸因于此客戶的任何標(biāo)簽。如果希望用戶看到店鋪的特定頁面,可以使用 return_to 字段。
注意:
SHOPLINE 的 Multipass 登錄使用電子郵件地址作為商店客戶的唯一標(biāo)識符。在 SHOPLINE 中注冊客戶時,在以下情況下,商家必須在標(biāo)識符字段中設(shè)置唯一標(biāo)識符:
2、該網(wǎng)站使用其他標(biāo)識符(如用戶名)
網(wǎng)站的兩個不同用戶可能會使用相同的電子郵件地址注冊。如果電子郵件地址始終是唯一的,則不需要設(shè)置“標(biāo)識符”字段。只有一個 SHOPLINE 帳戶可以使用特定的電子郵件地址。使用相同的電子郵件地址(即使使用不同的“標(biāo)識符”)注冊第二個客戶將導(dǎo)致錯誤。
3、使用 AES 加密 JSON 數(shù)據(jù)
要生成有效的 Multipass 登錄令牌,需要在 SHOPLINE 管理員中為提供密鑰。該密鑰用于導(dǎo)出兩個加密密鑰,一個用于加密,一個用于簽名。此密鑰派生是通過使用 SHA-256 哈希函數(shù)完成的(前 128 位用作加密密鑰,最后 128 位用作簽名密鑰)。
加密提供了保密性。它確保沒有人能讀取客戶數(shù)據(jù)。作為加密密碼,我們使用 AES 算法(128 位密鑰長度、CBC 操作模式、隨機(jī)初始化向量)。
4、使用 HMAC 對加密數(shù)據(jù)進(jìn)行簽名
簽名(也稱為消息身份驗證代碼)提供真實(shí)性。它確保多通令牌是真實(shí)的,并且沒有被篡改。我們使用帶有 SHA-256 哈希函數(shù)的 HMAC 算法,并對第 3 步的加密 JSON 數(shù)據(jù)(而不是第 2.2 步的明文 JSON 數(shù)據(jù))進(jìn)行簽名。
5、Base64 對二進(jìn)制數(shù)據(jù)進(jìn)行編碼
Multipass 登錄令牌現(xiàn)在由 128 位初始化向量、可變長度密文和 256 位簽名(按此順序)組成。此數(shù)據(jù)使用base64(URL安全變體,RFC 4648)進(jìn)行編碼。
6、將客戶重定向到 SHOPLINE 商店
一旦有了令牌,應(yīng)該會觸發(fā) HTTP GET 請求到 SHOPLINE 商店。
HTTP GET請求:api/user/account/login/multipass/insert_token_here
當(dāng)請求成功時(例如,令牌有效且未過期),客戶將登錄 SHOPLINE 商店。
Multipass 登錄令牌僅在很短的時間內(nèi)有效,每個令牌只能使用一次。出于這些原因,不應(yīng)該提前生成令牌,以便將其渲染到 HTML 站點(diǎn)中。應(yīng)該創(chuàng)建一個重定向 URL,在需要時實(shí)時生成令牌,然后自動重定向瀏覽器。
二、實(shí)施示例
以下顯示了 java 語言中令牌生成的基本示例實(shí)現(xiàn)。
public static void main(final String[] args) throws Exception { final String createAt = ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT); final Map<String, String> dataMap = new HashMap<>(); dataMap.put("email", "peter@shoplineapp.com"); dataMap.put("created_at", createAt); final String dataJson = "..."; //json string from dataMap; final String secret = "..."; final String token = generateToken(secret, dataJson); log.info("plaintext={}, token={}", dataJson, token); }public static String generateToken(final String secret, final String plaintext) throws Exception { // SHA-256 hash final MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); final byte[] encodedHash = messageDigest.digest(secret.getBytes(StandardCharsets.UTF_8)); final byte[] encryptedKey = new byte[16]; final byte[] signKey = new byte[16]; System.arraycopy(encodedHash, 0, encryptedKey, 0, 16); System.arraycopy(encodedHash, 16, signKey, 0, 16); // iv final byte[] iv = new byte[16]; new SecureRandom().nextBytes(iv); final SecretKeySpec encryptedKeySpec = new SecretKeySpec(encryptedKey, "AES"); final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, encryptedKeySpec, new IvParameterSpec(iv)); // encrypt byte array final byte[] encrypted = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8)); final byte[] ivEncryptedByte = new byte[iv.length + encrypted.length]; System.arraycopy(iv, 0, ivEncryptedByte, 0, iv.length); System.arraycopy(encrypted, 0, ivEncryptedByte, iv.length, encrypted.length); final Mac hmac = Mac.getInstance("HmacSHA256"); final SecretKeySpec signKeySpec = new SecretKeySpec(signKey, "HmacSHA256"); hmac.init(signKeySpec); // sign byte array, 256 bit final byte[] signByte = hmac.doFinal(ivEncryptedByte); final byte[] tokenBytes = new byte[ivEncryptedByte.length + signByte.length]; System.arraycopy(ivEncryptedByte, 0, tokenBytes, 0, ivEncryptedByte.length); System.arraycopy(signByte, 0, tokenBytes, ivEncryptedByte.length, signByte.length); String token = Base64.encodeBase64URLSafeString(tokenBytes); token = token.replace('+', '-') .replace('/', '_'); return token; }
三、安全考慮
SHOPLINE 鼓勵始終在客戶數(shù)據(jù)哈希中設(shè)置 remote_ip 字段,以便只有預(yù)期的瀏覽器才能使用令牌。我們還鼓勵使用安全的 HTTPS 連接向瀏覽器發(fā)送令牌。
應(yīng)該確保在主網(wǎng)站上注冊新帳戶需要驗證所使用的電子郵件地址。否則,有人可以使用別人的電子郵件地址注冊主網(wǎng)站,從而在 SHOPLINE 商店中訪問他的客戶帳戶。
四、常見問題
1、我有一個巨大的客戶數(shù)據(jù)庫。如何將其與 SHOPLINE 同步,以便我可以使用多通道登錄?
不需要同步任何內(nèi)容。一旦使用 Multipass 重定向客戶,我們將自動在 SHOPLINE 商店中為他們創(chuàng)建一個客戶帳戶(如果尚不存在)。
2、我的一些客戶已經(jīng)下了訂單 SHOPLINE。如何更新這些客戶,以便他們可以通過多通行證登錄?
可以使用客戶API 為客戶設(shè)置 multipass_identifier。需要將標(biāo)識符用于這些客戶帳戶的所有多通行證請求。
3、我的秘鑰被泄露了。我現(xiàn)在該怎么辦?
如果秘鑰泄露,可以在商店管理員中禁用它,再重新啟用將會生成一個新的秘鑰。這將使所有舊URL無效。應(yīng)該盡快這樣做,因為每個知道秘鑰的人都可能訪問每個客戶帳戶!
4、我可以在多個 SHOPLINE 商店之間使用 Multipass 登錄嗎?
不,Multipass 不能用于在多個 SHOPLINE 商店之間登錄,而無需重定向到外部網(wǎng)站。
5、Multipass登錄是否適用于批發(fā)渠道?
不,Multipass 不能與批發(fā)渠道一起使用。
6、remote_ip 字段是否支持 IPv6 地址?
不,僅支持 IPv4 地址。如果 remote_ip 與客戶數(shù)據(jù)哈希中指定的IP不匹配,Multipass 返回錯誤“無權(quán)使用 Multipass 登錄”。