计算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());
}