菠蘿派商城簽名規(guī)則是采用菠蘿派商城開發(fā)規(guī)范的平臺統(tǒng)一使用的簽名規(guī)則。目的為了防止API調(diào)用過程中被黑客惡意篡改,調(diào)用任何一個API都需要攜帶簽名,服務(wù)端會根據(jù)請求參數(shù),對簽名進(jìn)行驗證,簽名不合法的請求將會被拒絕。目前支持的簽名算法只支持MD5,簽名大體過程如下:
將除Sign參數(shù)外的所有“參數(shù) 參數(shù)值”進(jìn)行字典排序生成串,而后將AppSecret加到該串的首尾,將得到的字符串轉(zhuǎn)小寫,進(jìn)行MD5加密,此時的生成的串即為Sign。以抓單為例,若參數(shù)分別為以下值:
appkey=438b2f6ff103422a98a9349507293bb2
bizcontent={"OrderStatus":"JH_01","PlatOrderNo":"20182270207","StartTime":"2016-07-26 10:59:10","EndTime":"2016-08-02 10:59:10","TimeType":"JH_02","PageIndex":"1","PageSize":"20"}
method=Differ.JH.Business.GetOrder
token=9415c33b04d24c7dae320b0185f42fb0
按字典排序生成的串為:appkey438b2f6ff103422a98a9349507293bb2bizcontent{"OrderStatus":"JH_01","PlatOrderNo":"20182270207","StartTime":"2016-07-26 10:59:10","EndTime":"2016-08-02 10:59:10","TimeType":"JH_02","PageIndex":"1","PageSize":"20"}methodDiffer.JH.Business.GetOrdertoken9415c33b04d24c7dae320b0185f42fb0。
若Appsecret=5ee2084de90043be989d4d99d0dd0eaa,則帶簽名字符串為:
5ee2084de90043be989d4d99d0dd0eaaappkey438b2f6ff103422a98a9349507293bb2bizcontent{"OrderStatus":"JH_01","PlatOrderNo":"20182270207","StartTime":"2016-07-26 10:59:10","EndTime":"2016-08-02 10:59:10","TimeType":"JH_02","PageIndex":"1","PageSize":"20"}methodDiffer.JH.Business.GetOrdertoken9415c33b04d24c7dae320b0185f42fb05ee2084de90043be989d4d99d0dd0eaa
轉(zhuǎn)小寫:
5ee2084de90043be989d4d99d0dd0eaaappkey438b2f6ff103422a98a9349507293bb2bizcontent{"orderstatus":"jh_01","platorderno":"20182270207","starttime":"2016-07-26 10:59:10","endtime":"2016-08-02 10:59:10","timetype":"jh_02","pageindex":"1","pagesize":"20"}methoddiffer.jh.business.getordertoken9415c33b04d24c7dae320b0185f42fb05ee2084de90043be989d4d99d0dd0eaa
MD5加密后得到簽名:
347e07a557e2720256e64e1e828eff1b (注意,簽名也是小寫的)
C#簽名示例代碼
//獲得http請求傳參 var context = System.Web.HttpContext.Current; var appkey = context.Request["appkey"]; var token = context.Request["token"]; var method = context.Request["method"]; var bizcontent= context.Request["bizcontent"]; var sign=context.Request["sign"]; var appSecret = "5ee2084de90043be989d4d99d0dd0eaa"; //appSecret的值通過在菠蘿派中申請應(yīng)用獲得 //將參數(shù)加入排序字典。 var dic = new SortedDictionary<string, string>(); dic.Add("method", method); dic.Add("appkey", appkey); dic.Add("token", token); dic.Add("bizcontent", bizcontent); var newSign=Sign(dic,appSecret); if(sign!=newSign) { Response.Write("{\"code\":\"40000\",\"message\":\"Logical Error\",\"subcode\":\"GSE.VERIFYSIGN_FAILURE\",\"submessage\":\"簽名驗證失敗\"}"); } /// <summary> /// 生成簽名。 /// </summary> /// <returns></returns> private string Sign(SortedDictionary<string, string> dic,string appSecret) { //構(gòu)建待簽名的字符串。 var beSignText = string.Empty; foreach (string _key in dic.Keys) beSignText += _key + dic[_key]; //轉(zhuǎn)小寫生成簽名。 return this.MD5((appSecret + beSignText + appSecret).ToLower()); } /// <summary> /// 字符串生成MD5碼。 /// </summary> /// <param name="data">待MD5字符</param> /// <returns></returns> public string MD5(string data) { var bytes = Encoding.UTF8.GetBytes(data); var hashmd5 = new MD5CryptoServiceProvider(); byte[] byteOriginal = hashmd5.ComputeHash(bytes); StringBuilder ciphertext = new StringBuilder(32); for (int i = 0; i < byteOriginal.Length; i++) { ciphertext.Append(byteOriginal[i].ToString("x").PadLeft(2, '0')); } return ciphertext.ToString(); }
PHP簽名示例代碼
//獲得http請求傳參 $method = $_REQUEST['method']; $appkey = $_REQUEST['appkey']; $token = $_REQUEST['token']; $bizcontent = $_REQUEST['bizcontent']; $sign = $_REQUEST['sign']; $appSecret="5ee2084de90043be989d4d99d0dd0eaa"; //appSecret的值通過在菠蘿派中申請應(yīng)用獲得 $unsign=$appSecret."appkey".$appkey."bizcontent".$bizcontent."method".$method."token".$token.$appSecret; $newsign=md5(strtolower($unsign)); if($sign!=$newsign) { echo("{\"code\":\"40000\",\"message\":\"Logical Error\",\"subcode\":\"GSE.VERIFYSIGN_FAILURE\",\"submessage\":\"簽名驗證失敗\"}"); }
C++簽名示例代碼
String MD5UTF8String(String ASrc) { String strRet = ""; TIdHashMessageDigest5 *MD5Encode = new TIdHashMessageDigest5(); try { strRet = MD5Encode->HashStringAsHex(ASrc, Sysutils::TEncoding::UTF8 ).LowerCase(); } __finally { delete MD5Encode; } return strRet; } //--------------------------------------------------------------------------- void __fastcall TForm1::IdHTTPServerCommandGet(TIdContext *AContext, TIdHTTPRequestInfo *ARequestInfo, TIdHTTPResponseInfo *AResponseInfo) { String Method = ARequestInfo->Params->Values["method"]; String Appkey = ARequestInfo->Params->Values["appkey"]; String Token = ARequestInfo->Params->Values["token"]; String Bizcontent = ARequestInfo->Params->Values["bizcontent"]; String Sign = ARequestInfo->Params->Values["sign"]; String AppSecret="5ee2084de90043be989d4d99d0dd0eaa"; //appSecret的值通過在菠蘿派中申請應(yīng)用獲得 String Unsign = AppSecret + "appkey" + Appkey + "bizcontent" + Bizcontent + "method" + Method + "token" + Token + AppSecret ; String Newsign = MD5UTF8String(Unsign.LowerCase()).LowerCase(); if (Sign != Newsign) { AResponseInfo->ContentText = "{\"code\":\"40000\",\"message\":\"Logical Error\",\"subcode\":\"GSE.VERIFYSIGN_FAILURE\",\"submessage\":\"簽名驗證失敗\"}"; } }
注意事項:
所有的請求和響應(yīng)數(shù)據(jù)編碼皆為utf-8格式,URL里的所有參數(shù)名和參數(shù)值請做URL編碼。
所有API請盡量使用POST發(fā)起請求。