## 签名规则(Signature)说明 >[info] 说明:采用签名规则,可以确保数据交互的安全 ### 安全验证方式 客户端(或第三方平台)调用服务端接口获取数据,必须进行安全认证,ShopWind提供了两种种数据安全保障 ***** 1. 对于访问`不需要用户登录`后才能请求的接口,比如获取全局的类目数据,地区数据。ShopWind支持采用对传输参数进行SIGN签名的方式,目前支持的加密方式为:MD5(暂不支持其他方式的加密,以后可以拓展RSA等更高级的加密方式) 2. 对于`需要用户登录`后才能请求的接口,比如获取用户个人收货地址信息。ShopWind除了采用第一种SIGN方式的安全措施外,还通过`TOKEN`的方式实现第二重安全保障。 ***** ### 实施步骤 一、申请AppId和AppSecret,由平台商向接入方提供,如果是自用型接入,比如自己开发的小程序,APP需要对接获取数据,则也应确保每个客户端程序使用的都是唯一的AppId和密钥,客户端发起请求时,需要这两个参数来实现SIGN签名及验签。 二、组装需要签名的参数 1. 获取所有请求参数,不包括字节类型参数,如文件、字节流,剔除 sign 字段,剔除值为空的参数,并按照第一个字符的键值 ASCII 码递增排序(字母升序排序),如果遇到相同字符则按照第二个字符的键值 ASCII 码递增排序,以此类推。 2. 将排序后的参数与其对应值,组合成“参数=参数值”的格式,并且把这些参数用 & 字符连接起来,此时生成的字符串为待签名字符串,如下为所示(获取token值请参照:[获取TOKEN](access_token.md)): ``` appid=123&version=v3.0&sign_type=md5&token=1298kjiujhyt67njheyt62yghbvdgt32&timestamp=2020-9-11 10:23:34&format=json&params={"page":1,"limit": 20} ``` >[danger] 需要注意的是`params`参数,必须经过encode后再做拼接(即:PHP种的json\_encode或JS中的encodeURIComponent),在这里,我们建议将所有请求参数(包括appid,timestamp等 )都经过encode编码后再拼接,以便很好的处理因中文/特殊字符导致签名不一致的问题。 1. 拼接完后再与AppSecret 的值(假定AppSecret=abcdefg)拼接,我们使用md5加密方式生成SIGN ``` sign=md5(appid=123&version=v3.0...&params={"page:1,"limit"20}abcdefg) ``` 1. 将sign也加入到请求参数提中传输到服务端,之后就可以通过curl等发送到服务器请求数据了。 三、代码示例参考 ``` PHP代码: $post = [ "appid" => "123", "version" => "v3.0", "sign_type" => "md5", "token" => "1298kjiujhyt67njheyt62yghbvdgt32", "timestamp" => "2020-9-11 10:23:34", "format" => "json", "params" => json_encode([ "page" => 1, "limit" => 10 ]) ]; $post['sign'] = "参照步骤二第3点生成的sign值"; foreach($post as $key => $value) { $post[$key] = urlencode($value); } $gateway = 'http://www.xxx.com/userlist'; // user/list 为接口名 $post = json_encode($gateway, $post); $response = curl($post); $result = json_decode($response); if($result->code > 0) { // show errors message exit($result->message); } print_r($result->data); // TODO function curl($url, $post = null) { $ch = curl_init(); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json; charset=utf-8","Content-Length: ".strlen($post))); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, 1);//post提交方式 curl_setopt($ch, CURLOPT_POSTFIELDS, $post); //运行curl $res = curl_exec($ch); //var_dump( curl_error($ch) ); return $res; } ```