杭州女装网API


接口数据签名说明文档

<h1><strong>简要描述:</strong></h1> <p>注: <span style="color:red">经常有签名不对的情况!</span> 1、大多数 是因为 ,开发语言的默认排序方式会不一样,导致 参数拼接后的字符串不一样了! 建议 直接把 <span style="color:red">参数名 <strong>都改成小写或者大写</strong></span>,好排序! 【女装网获取参数时不区分大小写,没事的】 2、下面有C#和Java的示例代码: 3、 提供一个签名工具:<a href="http://open.hznzcn.com//sign_test.html">http://open.hznzcn.com//sign_test.html</a> ,可进行签名的测试 <strong>签名加密方式:</strong></p> <ul> <li>MD5</li> <li>utf-8编码</li> <li>32位</li> <li>大写</li> </ul> <h1><strong>签名规则</strong></h1> <p><strong><span style="color:red;font-size:25px;">第1步</span>:准备好接口参数,除了接口 需要的 业务参数 外,还包括整个开发平台所有接口都需要的 基础公告参数:app_key(女装网分配的AppKey)、access_token(女装网授权的token)、stamp(stamp为当前时间戳)。 </strong> 注:参数 access_token(女装网开放平台授权成功后的token),如果某个api 是 仅限授权用户使用的,该access_token就一定要参与签名,如果某api可以 匿名可访问 (非仅限授权用户),access_token可以不传参)</p> <p><strong><span style="color:red;font-size:25px;">第2步</span>:将各个接口参数(stamp、app_key、access_token及其它业务参数),以参数名进行升序排序,排序后,再以 参数名和参数值 的形式,拼接形成一个待签名的 字符串data。</strong></p> <ul> <li>优先 数字、其次 小写字母、最后 大写字母 的顺序,进行升序排序</li> <li>【重点】各个语言的排序可能会有差异,可以将参数名全小写,再升序排序,女装网开放平台对请求参数的名称,大小写不敏感</li> <li>可以参考C#语言中的 SortedDictionary&lt;string, string&gt; 类型的排序</li> <li><span style="color:red;font-size:25px;">【重点】拼接字符串时,如果参数的值为null或者为空,请过滤,不要拼接,参与签名</span></li> </ul> <p><strong><span style="color:red;font-size:25px;">第3步</span>:把私钥(Secret,女装网提供),拼到第2步拼接好后的 字符串data 最后面</strong></p> <p><br/> <br/></p> <h1><strong>下面是具体示例图和过程</strong></h1> <ul> <li>json参数是<a href="https://www.showdoc.cc/230407611622153?page_id=1313862750462126" title=" 获取授权,token"> 获取授权,token</a> 的请求参数,这里用来演示</li> </ul> <pre><code>{ "app_key": "1", "grant_type": "password", "loginway": "1", "username": "18888888888", "password": "PPPPPPPPPPPPPPPP", "stamp": "637199749398998058" } </code></pre> <p>1、准备参数数据阶段(下图,参数未排序) <img src="https://www.showdoc.cc/server/api/common/visitfile/sign/907a3c2299385ff1e0257292385b194c?showdoc=.jpg" alt="" /></p> <p>2、签名前阶段1,(下图,已经对参数进行了排序) <img src="https://www.showdoc.cc/server/api/common/visitfile/sign/7cb4b1f16e98b47931800c9fb92bdb14?showdoc=.jpg" alt="" /></p> <p>3、签名前阶段2(排序后,所有参数的key和值进行 拼接)</p> <pre><code>以 参数名和参数值 的形式,拼接形成一个字符串【如果参数没值,就过滤不参与拼接】; 得到的字符串为:app_key1grant_typepasswordloginway1passwordPPPPPPPPPPPPPPPPstamp637199749398998058username18888888888</code></pre> <p>4、签名前阶段3(拼接私钥Secret)【生成最终的待签名字符串】</p> <pre><code>把私钥(Secret:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),拼到 签名前阶段2 的带的 字符串 最后面, 最后得到: app_key1grant_typepasswordloginway1passwordPPPPPPPPPPPPPPPPstamp637199749398998058username18888888888xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</code></pre> <p>5、 进行签名:使用MD5(utf-8编码, 32位 大写)对以上字符串加密</p> <pre><code>最终得到的签名字符串:A4D0EF594C0996658E552A555E37CCF9</code></pre> <p>6、提供一个 签名工具:<a href="http://open.hznzcn.com//sign_test.html">http://open.hznzcn.com//sign_test.html</a> ,可进行签名的测试 <img src="https://www.showdoc.cc/server/api/common/visitfile/sign/025b62c9076ad3ebffd2170a7ab560f4?showdoc=.jpg" alt="" /></p> <h1><strong>签名的参考代码</strong></h1> <ul> <li>下面有两个示例代码:C#和Java</li> </ul> <h3>C#示例代码:</h3> <pre><code class="language-csharp">/// &lt;summary&gt; /// 取得数据签名 /// &lt;/summary&gt; /// &lt;param name="sParaTemp"&gt;参数字典&lt;/param&gt;. /// &lt;param name="appSecret"&gt;女装网提供的appSecret&lt;/param&gt; /// &lt;returns&gt;&lt;/returns&gt; public static string GetSign(SortedDictionary&lt;string , string&gt; sParaTemp, string appSecret) { StringBuilder sb = new StringBuilder(); //按keyvaluekeyvalue...拼装 foreach (KeyValuePair &lt;string, string&gt; kv in sParaTemp) { //如果参数名和参数值不为空,才拼接 if (!string .IsNullOrEmpty(kv.Key) &amp;&amp; !string.IsNullOrEmpty(kv.Value) &amp;&amp; kv.Key != "") { sb.Append(kv.Key).Append(kv.Value); } } //把密钥追加到参数值末尾 sb.Append(appSecret); //使用utf-8编码,MD5加密 MD5 md5 = MD5 .Create(); byte[] bytes = md5.ComputeHash(Encoding .UTF8.GetBytes(sb.ToString())); //把二进制转化为大写的十六进制 StringBuilder result = new StringBuilder(); for (int i = 0; i &lt; bytes.Length; i++) { result.Append(bytes[i].ToString( "X2")); } return result.ToString(); } </code></pre> <h3>Java示例代码:</h3> <pre><code class="language-java">/** * 获取签名 */ public static String getSign(Map&lt;String, String&gt; map,String secret){ String sign= ""; Map&lt;String, String&gt; signMap = paraFilter(map);//过滤空值 String str = createLinkString(signMap)+secret;//把参数拼接成 待签名的字符串 sign = Md5Util.encode(str);//Md5加密,下面提供了 Md5Util类【 Md5Util.java】 return sign; } /** * 参数过虑,空值过虑,并返回过虑后的,参与签名的 Map */ public static Map&lt;String, String&gt; paraFilter(Map&lt;String, String&gt; sArray) { Map&lt;String, String&gt; result = new HashMap&lt;String, String&gt;(); if (sArray == null || sArray.size() &lt;= 0) { return result; } for (String key : sArray.keySet()) { String value = sArray.get(key); //参数名或者参数值为空,过滤掉 if (value == null || value.equals("") || key.equalsIgnoreCase("sign") || key.equalsIgnoreCase("sign_type")) { continue; } result.put(key, value); } return result; } /** * 把参数拼接成 待签名的字符串 */ public static String createLinkString(Map&lt;String, String&gt; params) { List&lt;String&gt; keys = new ArrayList&lt;String&gt;(params.keySet()); Collections.sort(keys);//进行排序;该sort仅适用于keys都是小写或者大写的情况,若存在大小写等复杂情况,可能需要优化排序 String prestr = ""; for (int i = 0; i &lt; keys.size(); i++) { String key = keys.get(i); String value = params.get(key); prestr = prestr + key + value; } return prestr; } </code></pre> <h3>Md5Util.java</h3> <pre><code class="language-java">package com.idorabox.core.utils; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.security.MessageDigest; public final class Md5Util { public static final String JT_CHARSET = "UTF-8"; private static final char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; public static String encode(File file) { FileInputStream in = null; MessageDigest md5 = null; try { in = new FileInputStream(file); FileChannel ch = in.getChannel(); MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); md5 = MessageDigest.getInstance("MD5"); md5.update(byteBuffer); } catch (Exception e) { e.printStackTrace(); } finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } return toHex(md5.digest()); } public static String encode(String arg) { if (arg == null) { arg = ""; } MessageDigest md5 = null; try { md5 = MessageDigest.getInstance("MD5"); md5.update(arg.getBytes(JT_CHARSET)); } catch (Exception e) { e.printStackTrace(); } return toHex(md5.digest()); } private static String toHex(byte[] bytes) { StringBuffer str = new StringBuffer(32); for (byte b : bytes) { str.append(hexDigits[(b &amp; 0xf0) &gt;&gt; 4]); str.append(hexDigits[(b &amp; 0x0f)]); } return str.toString(); } }</code></pre> <h3>PHP MD5代码</h3> <pre><code class="language-php">$s1=md5("待加密签名的字符串"); $signs=strtoupper($s1);</code></pre> <h3>Jquery MD5代码</h3> <ul> <li>需要导入md5的js</li> </ul> <pre><code class="language-javascript">var sign=$.md5("待加密签名的字符串").toUpperCase();</code></pre>

页面列表

ITEM_HTML