Multipass 登录适用于拥有单独网站和 SHOPLINE 商店的店主。它将用户从网站重定向到 SHOPLINE 商店,并使用他们用于注册原始网站的相同电子邮件地址无缝登录。如果还没有该电子邮件地址的帐户,则会用该电子邮件地址创建一个新账户。无需同步任何客户数据库。
目录
如何使用 Multipass
在 SHOPLINE 中启用 Multipass 登录
- 在 SHOPLINE admin 中,点击【设置】>【客户账户】>【客户账户类型】。请先确保您已选择【经典客户账户】。然后,找到【通过 Multipass 登录】,点击【启用】。
-
启用后,将与您共享一个【加密密钥】。您需要此密钥才能生成令牌,用于允许客户登录您的店铺。
为避免安全隐患,请确保您的密钥保密。
使用 JSON 对客户信息进行编码
客户信息表示为哈希,该哈希必须至少包含客户的电子邮件地址和当前时间戳(ISO8601 编码)。您还可以附上客户的名字、姓氏或多个送货地址。或者,您可以包含客户当前浏览器会话的 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”设置为逗号分隔的单字值列表来将标签归因于客户。这些标签将覆盖您可能已经归因于此客户的任何标签。
如果您希望您的用户看到您店铺的特定页面,您可以使用 return_to 字段。
备注: SHOPLINE 的 Multipass 登录使用电子邮件地址作为商店客户的唯一标识符。在 SHOPLINE 中注册客户时,在以下情况下,商家必须在标识符字段中设置唯一标识符:
|
使用 AES 加密 JSON 数据
要生成有效的 Multipass 登录令牌,您需要在 SHOPLINE 管理员中为您提供密钥。该密钥用于导出两个加密密钥,一个用于加密,一个用于签名。此密钥派生是通过使用 SHA-256 哈希函数完成的(前 128 位用作加密密钥,最后 128 位用作签名密钥)。
加密提供了保密性。它确保没有人能读取客户数据。作为加密密码,我们使用 AES 算法(128 位密钥长度、CBC 操作模式、随机初始化向量)。
使用 HMAC 对加密数据进行签名
签名(也称为消息身份验证代码)提供真实性。它确保多通令牌是真实的,并且没有被篡改。我们使用带有 SHA-256 哈希函数的 HMAC 算法,并对第 3 步的加密 JSON 数据(而不是第 2.2 步的明文 JSON 数据)进行签名。
Base64 对二进制数据进行编码
Multipass 登录令牌现在由 128 位初始化向量、可变长度密文和 256 位签名(按此顺序)组成。此数据使用base64(URL安全变体,RFC 4648)进行编码。
将您的客户重定向到您的 SHOPLINE 商店
一旦您有了令牌,您应该会触发 HTTP GET 请求到您的 SHOPLINE 商店。
HTTP GET请求:api/user/account/login/multipass/insert_token_here
当请求成功时(例如,令牌有效且未过期),客户将登录您的 SHOPLINE 商店。
Multipass 登录令牌仅在很短的时间内有效,每个令牌只能使用一次。出于这些原因,您不应该提前生成令牌,以便将其渲染到 HTML 站点中。您应该创建一个重定向 URL,在需要时实时生成令牌,然后自动重定向浏览器。
实施示例
以下显示了 java 语言中令牌生成的基本示例实现。
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 鼓励您始终在客户数据哈希中设置 remote_ip 字段,以便只有预期的浏览器才能使用令牌。我们还鼓励您使用安全的 HTTPS 连接向浏览器发送令牌。
您应该确保在主网站上注册新帐户需要验证所使用的电子邮件地址。否则,有人可以使用别人的电子邮件地址注册您的主网站,从而在您的 SHOPLINE 商店中访问他的客户帐户。
常见问题
Q1:我有一个巨大的客户数据库。如何将其与 SHOPLINE 同步,以便我可以使用多通道登录?
A1:您不需要同步任何内容。一旦您使用 Multipass 重定向客户,我们将自动在您的 SHOPLINE 商店中为他们创建一个客户帐户(如果尚不存在)。
Q2:我的一些客户已经下了订单 SHOPLINE。如何更新这些客户,以便他们可以通过多通行证登录?
A2:您可以使用客户API 为客户设置 multipass_identifier。您需要将标识符用于这些客户帐户的所有多通行证请求。
Q3:我的秘钥被泄露了。我现在该怎么办?
A3:如果您的秘钥泄露,可以在您的商店管理员中禁用它,再重新启用将会生成一个新的秘钥。这将使所有旧URL无效。您应该尽快这样做,因为每个知道秘钥的人都可能访问每个客户帐户!
Q4: 我可以在多个 SHOPLINE 商店之间使用 Multipass 登录吗?
A4: 不,Multipass 不能用于在多个 SHOPLINE 商店之间登录,而无需重定向到外部网站。
Q5:Multipass登录是否适用于批发渠道?
A5:不,Multipass 不能与批发渠道一起使用。
Q6:remote_ip 字段是否支持 IPv6 地址?
A6:不,仅支持 IPv4 地址。如果 remote_ip 与客户数据哈希中指定的IP不匹配,Multipass 返回错误“您无权使用 Multipass 登录”。
如何联系我们
SHOPLINE 拥有专业的本地支持团队,为有需求和疑惑的商家提供帮助。您可以通过联系 SHOPLINE 店铺后台及官方网站的实时客服来寻求 SHOPLINE 的帮助。
*如有 SHOPLINE 功能使用感受或需求建议,快点击【功能反馈】告诉我们吧!
评论