文档 规范的文档对接口的开发有着至关重要的作用,规范的文档能够使 双方对接口的定义以及接口的参数都有一个明确的概念,便于沟通和联调。

  在接口的开发过程中,为了保证传递参数的传递的私密性,参数传输是需要加签的,接口提供方提供了一种验签规则,接口的调用方提供合适的参数后通过加签的操作以参数的形式传输给接口的提供方

  下面提供一种验签的思路 

    step1: 拼接参数字符串将除sign以外的请求参数(包括标准参数,除非有特别说明)按照参数名称的字典升序排列,然后按此顺序,将”参数名=参数值”用”&”符号连接,结果形如:”参数名1=参数值1&参数名2=参数值2&…&参数名n=参数值n”。

    注意事项:

        1)        参数值应为urlencode过后的字符串。

        2)        仅对接口定义中声明且请求参数列表中包含的参数(包括空值)进行签名。

        3)        参数值不作去除空格。

    step2: 计算参数字符串&appSecret的hash摘要digest=md5(参数字符串&appSecret)

    step3: 将二进制的摘要转换为16进制表示sign=toHex(digest),注:签名比较无需区分大小写

      /// <summary>
/// 验证该商家数据和签名
/// </summary>
/// <param name="requestData"></param>
/// <returns></returns>
private bool CheckSignValidate(ParameterWrapper requestData)
{
string method = requestData[SystemMethodParameterNames.method];
string appid = requestData[SystemMethodParameterNames.app_id];
string appSecret = string.Empty;
List<RouteConfig> routeList = RouteConfigManager.GetRouteConfig();
var routeConfigInfo = routeList.First(f => f.Name == method.Trim().ToLower());
if (appid.ToLower() == ConfigurationManager.AppSettings["DataExchangeCenter_AppID"].ToLower())
{
//账册中间件:
if (routeConfigInfo.CallerType != )
{
throw new SysException(new KeyValuePair<string, string>("-4", "用户不支持调用当前API接口!"));
}
appSecret = ConfigurationManager.AppSettings["DataExchangeCenter_AppSecret"];
}
else
{
//其他系统/商家:
if (routeConfigInfo.CallerType != )
{
throw new SysException(new KeyValuePair<string, string>("-4", "用户不支持调用当前API接口!"));
}
appSecret = AppSecretKeyDA.GetAppSecretKeyByKJTAppID(appid);
if (string.IsNullOrEmpty(appSecret))
{
throw new SysException(SysExceptionContent.getInvalidIdentityId());
}
} SellerAPIParameter sellerParam = new SellerAPIParameter() { SecretKey = CryptoManager.GetCrypto(CryptoAlgorithm.DES).Encrypt(appSecret) }; if (sellerParam == null)
{
throw new SysException(SysExceptionContent.getNoFoundSeller());
}
if (string.IsNullOrEmpty(sellerParam.SecretKey))
{
throw new SysException(SysExceptionContent.getSecureKeyNullOrEmpty());
}//对数据库中取出的SecretKey进行解密
sellerParam.SecretKey = CryptoManager.GetCrypto(CryptoAlgorithm.DES).Decrypt(sellerParam.SecretKey); SignatureType signatureType = SignatureType.MD5;
SignatureBuilder builder = new SignatureBuilder(sellerParam.SecretKey, signatureType, requestData); string sign = builder.BuildSignature();
string requestSign = requestData[SystemMethodParameterNames.sign].ToLower();
return requestSign == sign;
}

    上面是接口的提供方验签的方法,思路的实现就是上面的部分,具体签名的生成实在SignatureBuilder 这个类中实现

    测试的时候模拟了接口调用方,用的是一个Winform的简单窗体

    

  private void button1_Click(object sender, EventArgs e)
{
System.Text.UTF8Encoding encoding = new UTF8Encoding(); StringBuilder sb = new StringBuilder(); sb.Append("method=CreatePO&");
sb.Append("version=1.0&");
sb.Append("appid=32&");
sb.Append("data=");
sb.Append("{\"MerchantSysNo\":32,\"WarehouseID\":51,\"CallBackUrl\":\"http://localhost:9998/open.api\",\"ETATime\":\"2015-03-20\",\"HalfDay\":\"PM\",\"Items\":[{\"MerchantProductID\":\"5900820010218\",\"Qty\":10},{\"MerchantProductID\":\"4902508040327\",\"Qty\":20}]}");
string requestBody = sb.ToString();
NameValueCollection nv = new NameValueCollection();
if (requestBody.Contains('&'))
{
foreach (var item in requestBody.Split('&'))
{
nv.Add(item.Split('=')[], item.Split('=')[]);
}
}
else
{
nv.Add(requestBody.Split('=')[], requestBody.Split('=')[]); } ParameterWrapper parameters = GetParameterWrapperFromNameValueCollection(nv); SignatureType signatureType = SignatureType.MD5;
SignatureBuilder builder = new SignatureBuilder("", signatureType, parameters); string sign = builder.BuildSignature(); sb.Append("&sign=").Append(sign); byte[] rdata = encoding.GetBytes(sb.ToString()); HttpWebRequest reqclient = WebRequest.Create("http://localhost:9998/open.api") as HttpWebRequest; reqclient.Method = "POST";
reqclient.ContentType = "application/x-www-form-urlencoded";
reqclient.ContentLength = rdata.Length;
Stream newStream = reqclient.GetRequestStream();
newStream.Write(rdata, , rdata.Length);
newStream.Close(); // Get response
HttpWebResponse myResponse = (HttpWebResponse)reqclient.GetResponse();
StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8);
string content = reader.ReadToEnd(); label1.Text = content; }
private ParameterWrapper GetParameterWrapperFromNameValueCollection(NameValueCollection nv)
{
ParameterWrapper parameter = new ParameterWrapper();
foreach (string key in nv.AllKeys)
{
string value = nv[key];
value = HttpUtility.UrlDecode(nv[key], Encoding.UTF8); parameter.Add(key, value);
}
return parameter;
}

    这样就实现了接口的开发以及调用的过程,当然这只是接口开发中的一部分,剩下的内容大部分都是和之前的模块开发没有什么太大的区别,实现数据的处理。

WebApi接口开发的更多相关文章

  1. WebAPI接口开发实践

    背景 在团队两年多陆续负责了几个项目的开发上线已经代码的review,特别是对老项目的重构过程中,发现之前的API设计是没有任何规范和约定的,不同的开发同学有不同的习惯,因此需要一套规范去约定,现在分 ...

  2. 微信JSAPI 公众号支付 H5支付以及APP支付 WEBAPI接口开发测试

    统一下单入口 调用该方法入口: public void WxPayAPI() { //string PayPrice ="99.9"; ////订单号 //string Payor ...

  3. ASP.NET Aries 高级开发教程:如何写WebAPI接口

    前提: 最近,有不少同学又问到,Aries里如何提供WebAPI接口? 针对这个问题,今天给顺路写个教程,其实呢,很简单的. 方式一:直接用WebService提供接口. 用这种方式,直接添加接口就可 ...

  4. C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解

    前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi的园友们速速动起来,跟着博主一起来学习吧.之前分享过一篇 C#进阶系列——WebApi接口传参不再困惑:传参详解  ...

  5. 《连载 | 物联网框架ServerSuperIO教程》- 13.自定义视图显示接口开发,满足不同的显示需求

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

  6. 利用委托与Lambada创建和调用webapi接口

    前言 现在项目中用的是webapi,其中有以下问题:    1.接口随着开发的增多逐渐增加相当庞大. 2.接口调用时不好管理. 以上是主要问题,对此就衍生了一个想法: 如果每一个接口都一个配置文件来管 ...

  7. QuickWebApi2:使用Lambda方式,完成对WebApi的开发和调用-文档的生成

    续 QuickWebApi:使用Lambda方式,完成对WebApi的开发和调用 上一篇完成了主要的功能,本次修订主要重构了对接口文档的生成规范,使之可读性更佳,甚至可以作为接口文档进行发布(当然,在 ...

  8. QuickWebApi:使用Lambada方式,完成对WebApi的开发和调用。

    QuickWebApi 目的:使用Lambada方式,完成对WebApi的开发和调用. 缘由:为了解耦服务和展现,将越来越多的使用WebApi提供各种服务:随着服务的细化,WebApi的接口将越来越多 ...

  9. WebApi 接口返回值类型详解 ( 转 )

    使用过Webapi的园友应该都知道,Webapi的接口返回值主要有四种类型 void无返回值 IHttpActionResult HttpResponseMessage 自定义类型 此篇就围绕这四块分 ...

随机推荐

  1. [HNOI 2013] 旅行 (数学)

    感觉此题难啊,数学还是太渣了,看了半天的题解才算明白了点儿. 题目大意 给一个长度为n且仅由1和-1组成的序列ai, i = 1, 2, ..., n,每个位置都有另一个值vi,要求用某种方案将序列划 ...

  2. SpringMVC拦截器(实现登录验证拦截器)

    本例实现登陆时的验证拦截,采用SpringMVC拦截器来实现 当用户点击到网站主页时要进行拦截,用户登录了才能进入网站主页,否则进入登陆页面 核心代码 首先是index.jsp,显示链接 <%@ ...

  3. 二、MLlib统计指标之关联/抽样/汇总

    汇总统计[Summary statistics]: Summary statistics提供了基于列的统计信息,包括6个统计量:均值.方差.非零统计量个数.总数.最小值.最大值. import org ...

  4. jsPlumb开发入门教程(实现html5拖拽连线)

    jsPlumb是一个强大的JavaScript连线库,它可以将html中的元素用箭头.曲线.直线等连接起来,适用于开发Web上的图表.建模工具等.它同时支持jQuery+jQuery UI.MooTo ...

  5. [转]getResource()和getResourceAsStream以及路径问题

    原文链接:http://blog.sina.com.cn/s/blog_4b5bc0110100g22w.html 用JAVA获取文件,听似简单,但对于很多像我这样的新人来说,还是掌握颇浅,用起来感觉 ...

  6. USB2.0速度识别

    我们知道USB2.0向下兼容USB1.x,即高速2.0的hub能支持所有的速度类型的设备,而USB1.x的hub不能支持高速设备(High Speed Device).因此,如果高速设备挂到USB1. ...

  7. sys--system-sysdba-sysoper用户区别

    当Oracle 数据库安装完毕后,系统会自动创建sys和system这两个帐户.1.sys :缺省密码为CHANGE_ON_INSTALL ,且被授予DBA角色system :缺省密码为MANAGER ...

  8. C#高级知识点概要(3) - 特性、自动属性、对象集合初始化器、扩展方法、Lambda表达式和Linq查询

    1.特性(Attributes) 特性(Attributes),MSDN的定义是:公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型.字段.方法 ...

  9. MySQL 覆盖索引

    通常大家都会根据查询的WHERE 条件来穿件合适的索引,不过这只是索引优化的一个方面.设计优秀的索引应该考虑到整个查询,而不单单是WHERE 条件部分.索引确实是一种查找数据的高效方式,但是MySQL ...

  10. Java系列--第七篇 基于Maven的Android开发实战项目

    本篇是基于<Android应用案例开发大全,吴亚峰等著>的项目开发实例源码,其中有些图片,我做了一些修改,用于个人学习,请勿用于商业. 1, 日程管理专家 mvn archetype:ge ...