计算post请求的sign参数
1.待签名字符串请求数据者,post的参数(除apiKey、 *可选参数不参与签名), 将用来计算sign
对于如下的参数数组:
string[] parameters={ "productId=1", "quantity=1", "tel=111****1111", "collectedRemark=" }
对数组里的每一个值从a 到z 的顺序排序,若遇到相同首字母,则看第二个字母, 以此类推。排序完成之后,再把所有数组值以“&”字符连接起来,如:
collectedremark=&productid=1&quantity=1&tel=111****1111
这串字符串便是待签名字符串
注意:1.没有值的参数需传递空值,也需包含到待签名数据中,如上例中的collectedRemark;
2.根据HTTP协议要求,传递参数的值中如果存在特殊字符(如:&、@等),那么该值需要做URL Encoding,这样请求接收方才能接收到正确的参数值。待签名数据应该是原生值而不是encoding 之后的值。例如:调用某接口需要对请求参数email 进行数字签名,那么待签名数据应该是email=test@msn.com,而不是email=test%40msn.com;
3.待签名字符串全部字母转换为小写字母
将待签名字符串后,需要把apiSecret直接拼接到待签名字符串前面,形成新的字符串,利用MD5的签名函数对这个新的字符串进行签名运算,并将签名结果字符串全部字母转换为大写字母。得到的字符串赋值给sign。
//调用此函数提供接口所有参数,将生成用于post的参数串$parmstring,同时生成签名字符串$sign,并进行远程请求返回输出内容 //type 1:json 2:txt function build_parm_sign($parms, $typ=1, $reqURI="", $formMethod = "GET") { //$parms格式为 array("s"=>是否参与签名true/false,"v"=>值) $parms["apiKey"] = array("s"=>false,"v"=>$this->apiKey); ksort($parms); $this->parmstring = ''; $reqParams = array(); $signParams = array(); foreach($parms as $key => $value){ $reqParams["$key"] = urlencode($value["v"]); if(!$value["s"]) continue; $signParams[] = "$key=$value[v]"; } $signstring = $this->apiSecret . strtolower(implode("&",$signParams)); $sign = strtoupper(md5($signstring)); $reqParams["sign"] = "$sign"; $t = new transport(-1,5,-1,true); $realUrl = empty($reqURI) ? $this->api_url : $reqURI; $respon = $t->request($realUrl, $reqParams, $formMethod); if($respon) { switch ($typ) { case 1: return json_decode($respon["body"],true); case 2: return $respon["body"]; } } else return array('ErrorCode'=>'999','Success'=>false,'Message'=>'服务器调用失败API级错误,'.$realUrl); }
/// <summary> /// 制造签名 /// </summary> /// <param name="parms"></param> /// <param name="queryString"></param> /// <returns>签名后字符串</returns> private string BuildSign(NameValueCollection parms, out string queryString) { queryString = ""; string[] keys = parms.AllKeys; ArrayList al = new ArrayList(); Array.Sort(keys); foreach (string a in keys) { if (!string.IsNullOrEmpty(queryString)) queryString += "&"; queryString += $"{a}=" + (string.IsNullOrEmpty(parms[a]) ? "" : HttpUtility.UrlEncode(parms[a])); al.Add($"{a}={parms[a]}"); } return EncryptHelper.MD5Encode(ApiSecret + string.Join("&", al.ToArray()).ToLower()); }