用户数据接入
第三方接入支持是为已有网站,将用户导入店铺设计的功能。比如,你正在经营一个论坛或者门户(myforum.com),它有自己的用户系统。之后,你在友好速搭创建了店铺(store.myforum.com)。你可以把店铺链接,放在之前的网站,这个链接就是按照接入规则生成,用户点击这个链接后,可以跳转并直接登录店铺。
使用过程如下:
可以参考如下的代码示例:
1. 启用第三方接入
通过登录友好速搭店铺后台,进入到基础设置,可以看到第三方接入支持这个选项。
开启后,就可以获取到接入密钥,该密钥将用于生成接入系统顾客系统的链接生成。密钥请妥善保管。
2. 准备参数
参数字段的详细描述:
字段 | 描述 |
---|---|
uid | 顾客唯一标识,用于登录(也可用于找回密码或设置密码),与type有关: type=email ,为邮件地址; type=mobile ,为手机号码;type=name ,为用户名;type in [douban, weibo, qq, renren, netease, weixin] ,为社交平台的用户标识。 |
type | 顾客注册类型:email 邮箱注册mobile 手机注册name 用户名注册douban 豆瓣帐号授权注册weibo 微博帐号授权注册qq QQ帐号授权注册renren 人人帐号授权注册netease 网易帐号授权注册weixin 微信帐号授权注册 |
name | 帐号昵称 |
return_type | 返回类型,不传默认为redirect ,包括:redirect 完成登录并跳转json 完成登录并返回json(注意:如使用json 类型返回请生成好后在浏览器端触发调用,因为该次访问中会完成登录并写入cookie到浏览器端中) |
redirect_url | 登录店铺后跳转链接(仅redirect_type=redirect 时有用),默认跳转到店铺首页。可以指定跳转路径,例如: /products/周年庆特惠商品 。 |
将用户信息,组装成为JSON格式数据,例如:
{
uid: "test@youhaosuda.com",
type: "email",
name: "test"
}
将上述JSON数据,序列化为字符串:
{\"uid\":\"test@youhaosuda.com\",\"type\":\"email\",\"name\":\"test\"}
使用AES算法对字符串进行加密,将接入密钥的前16个字节作为密钥(Secret key),店铺的接入密钥的后16个字节作为初始化向量(Initialization vector),使用AES算法进行加密,设定密钥长度为128bit,块加密模式(Block cipher mode)为CBC(Cipher-block chaining)。
AES(Advanced Encryption Standard)是一种非对称的加密算法,通过它加密用户信息字符串后,可以保证传输过程中保密性,只有拥有密钥人才能解读加密过的信息。
对加密后的内容进行 Base64 (RFC 4648)编码。
将上述序列化的JSON字符串,以095AE461E2554EED8D12F19F9662247E
为接入密钥进行 AES 加密并通过 Base64 编码,可得:
mJgEpH-ja_sBlYG_W3HcbekE_HP2yQVrlX2hu8AKM8F5JjPFTRYBwc62HGhCZgfyf3FxECC9u-tcnmsZcheENw==
3. 跳转到店铺
携带 Base64 编码后的内容,拼接到链接地址并跳转,链接地址格式:
[店铺主域名]/account/multipass/login/[Base64编码后的字符串]
。
javascript示例
不推荐在浏览器客户端进行加密,容易泄漏接入密钥。在线示例(注,需翻墙)。
<script src='https://code.jquery.com/jquery-1.11.2.min.js'></script>
<script src='http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js'></script>
<script>
function Encrypt(secret_key, data){
var key = CryptoJS.enc.Utf8.parse(secret_key.substr(0, 16));
var iv = CryptoJS.enc.Utf8.parse(secret_key.substr(16, 16));
var srcs = CryptoJS.enc.Utf8.parse(data);
var encrypted = CryptoJS.AES.encrypt(srcs, key, { iv: iv,mode:CryptoJS.mode.CBC});
return encrypted.toString().replace(/\+/g, '-').replace(/\//g, '_');
}
$(document).ready(function(){
// 用户信息JSON
var customer_data = JSON.stringify({"uid":"test@youhaosuda.com","type":"email","name":"test"});
var secret_key = '【接入密钥】';
var shop_domain = '【店铺主域名】';
var encrypt_data = Encrypt(secret_key, customer_data);
window.location.href = 'http://' + shop_domain + '/account/multipass/login/' + encrypt_data;
});
</script>
ruby示例
在线示例(注,需翻墙)。
require "openssl"
require "base64"
require "time"
require "json"
class YHSDMultipass
attr_accessor :cipher_key
attr_accessor :cipher_iv
def initialize(key)
@cipher_key = key[0, 16]
@cipher_iv = key[16, 16]
end
def aes_encrypt(data)
cipher = OpenSSL::Cipher::Cipher.new("aes-128-cbc")
cipher.encrypt
cipher.key = @cipher_key
cipher.iv = @cipher_iv
ciphertext = cipher.update(data) + cipher.final
Base64.urlsafe_encode64(ciphertext)
end
end
# 用户信息JSON
customer_data = {
"uid" => "test@youhaosuda.com",
"type" => "email",
"name" => "test"
}
secret_key = '【接入密钥】'
shop_domain = '【店铺主域名】'
encrypt_data = YHSDMultipass.new(secret_key).aes_encrypt(customer_data.to_json)
redirect_to URI.join(shop_domain ,"/account/multipass/login/#{encrypt_data}").to_s
java示例
在线示例(注,需翻墙)。
import java.io.UnsupportedEncodingException;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
// Mr Siu contribute at 2015-06-18
class AES {
static Cipher cipher;
static final String CIPHER_ALGORITHM_CBC = "AES/CBC/PKCS5Padding";
static Key secretKey;
static IvParameterSpec iv;
public static void main(String[] args) throws Exception {
// 用户信息
String customerData = "{\"uid\":\"test@youhaosuda.com\",\"type\":\"email\",\"name\":\"test\"}";
String strKey = "【接入密钥】";
String shopDomain = "【店铺主域名】";
String strEncrypt = aesEncrypt(strKey, customerData);
String redirectUrl = "http://" + shopDomain + "/account/multipass/login/" + strEncrypt;
System.out.println("customerData: " + customerData);
System.out.println("customerDataEncrypt: " + strEncrypt);
System.out.println("redirectUrl: " + redirectUrl);
}
/**
* 使用AES 算法 加密,默认模式 AES/CBC/PKCS5Padding
*/
static String aesEncrypt(String strKey, String strData) throws Exception {
cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);
secretKey = getKey(strKey);
iv = getIV(strKey);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
byte[] encrypt = cipher.doFinal(strData.getBytes());
return Base64.getUrlEncoder().encodeToString(encrypt);
}
static IvParameterSpec getIV(String strIv) throws UnsupportedEncodingException {
byte[] arrBTmp = strIv.getBytes("UTF-8");
byte[] arrB = new byte[16];
for (int i = 0; i + 16 < arrBTmp.length && i < arrB.length; i++) {
arrB[i] = arrBTmp[i + 16];
}
return new IvParameterSpec(arrB);
}
static Key getKey(String strKey) throws Exception {
byte[] arrBTmp = strKey.getBytes("UTF-8");
byte[] arrB = new byte[16];
for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
arrB[i] = arrBTmp[i];
}
return new SecretKeySpec(arrB, "AES");
}
}