webapi 访问https接口 - CSDN
精华内容
参与话题
  • api接口安全以及https

    千次阅读 2018-05-02 23:10:09
    一:加密方法:1,对称加密AES,3DES,DES等,适合做大量...二:https下面是拷来的,写的很好,原文链接:http://baijiahao.baidu.com/s?id=1570143475599137&wfr=spider&for=pc前言HTTPS(全称:Hyp...

    一:加密方法:

    1,对称加密

    AES,3DES,DES等,适合做大量数据或数据文件的加解密。

    2,非对称加密

    RSA,Rabin。公钥加密,私钥解密。对大数据量进行加解密时性能较低。


    二:https

    下面是拷来的,写的很好,原文链接:http://baijiahao.baidu.com/s?id=1570143475599137&wfr=spider&for=pc

    前言

    HTTPS(全称:HyperText Transfer Protocol over Secure Socket Layer),其实 HTTPS 并不是一个新鲜协议,Google 很早就开始启用了,初衷是为了保证数据安全。 近两年,Google、Baidu、Facebook 等这样的互联网巨头,不谋而合地开始大力推行 HTTPS, 国内外的大型互联网公司很多也都已经启用了全站 HTTPS,这也是未来互联网发展的趋势。

    为鼓励全球网站的 HTTPS 实现,一些互联网公司都提出了自己的要求:

    1)Google 已调整搜索引擎算法,让采用 HTTPS 的网站在搜索中排名更靠前;

    2)从 2017 年开始,Chrome 浏览器已把采用 HTTP 协议的网站标记为不安全网站;

    3)苹果要求 2017 年App Store 中的所有应用都必须使用 HTTPS 加密连接;

    4)当前国内炒的很火热的微信小程序也要求必须使用 HTTPS 协议;

    5)新一代的 HTTP/2 协议的支持需以 HTTPS 为基础。

    等等,因此想必在不久的将来,全网 HTTPS 势在必行。

    概念

    协议

    1、HTTP 协议(HyperText Transfer Protocol,超文本传输协议):是客户端浏览器或其他程序与Web服务器之间的应用层通信协议 。

    2、HTTPS 协议(HyperText Transfer Protocol over Secure Socket Layer):可以理解为HTTP+SSL/TLS, 即 HTTP 下加入 SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL,用于安全的 HTTP 数据传输。

    如上图所示 HTTPS 相比 HTTP 多了一层 SSL/TLS

    SSL(Secure Socket Layer,安全套接字层):1994年为 Netscape 所研发,SSL 协议位于 TCP/IP 协议与各种应用层协议之间,为数据通讯提供安全支持。

    TLS(Transport Layer Security,传输层安全):其前身是 SSL,它最初的几个版本(SSL 1.0、SSL 2.0、SSL 3.0)由网景公司开发,1999年从 3.1 开始被 IETF 标准化并改名,发展至今已经有 TLS 1.0、TLS 1.1、TLS 1.2 三个版本。SSL3.0和TLS1.0由于存在安全漏洞,已经很少被使用到。TLS 1.3 改动会比较大,目前还在草案阶段,目前使用最广泛的是TLS 1.1、TLS 1.2。

    加密算法:

    据记载,公元前400年,古希腊人就发明了置换密码;在第二次世界大战期间,德国军方启用了“恩尼格玛”密码机,所以密码学在社会发展中有着广泛的用途。

    1、对称加密

    有流式、分组两种,加密和解密都是使用的同一个密钥。

    例如:DES、AES-GCM、ChaCha20-Poly1305等

    2、非对称加密

    加密使用的密钥和解密使用的密钥是不相同的,分别称为:公钥、私钥,公钥和算法都是公开的,私钥是保密的。非对称加密算法性能较低,但是安全性超强,由于其加密特性,非对称加密算法能加密的数据长度也是有限的。

    例如:RSA、DSA、ECDSA、 DH、ECDHE

    3、哈希算法

    将任意长度的信息转换为较短的固定长度的值,通常其长度要比信息小得多,且算法不可逆。

    例如:MD5、SHA-1、SHA-2、SHA-256 等

    4、数字签名

    签名就是在信息的后面再加上一段内容(信息经过hash后的值),可以证明信息没有被修改过。hash值一般都会加密后(也就是签名)再和信息一起发送,以保证这个hash值不被修改。

    详解

    一、HTTP访问过程

    抓包如下:

    如上图所示,HTTP请求过程中,客户端与服务器之间没有任何身份确认的过程,数据全部明文传输,“裸奔”在互联网上,所以很容易遭到黑客的攻击,如下:

    可以看到,客户端发出的请求很容易被黑客截获,如果此时黑客冒充服务器,则其可返回任意信息给客户端,而不被客户端察觉,所以我们经常会听到一词“劫持”,现象如下:

    下面两图中,浏览器中填入的是相同的URL,左边是正确响应,而右边则是被劫持后的响应

    所以 HTTP 传输面临的风险有:

    (1) 窃听风险:黑客可以获知通信内容。

    (2) 篡改风险:黑客可以修改通信内容。

    (3) 冒充风险:黑客可以冒充他人身份参与通信。

    二、HTTP 向 HTTPS 演化的过程

    第一步:为了防止上述现象的发生,人们想到一个办法:对传输的信息加密(即使黑客截获,也无法破解)

    如上图所示,此种方式属于对称加密,双方拥有相同的密钥,信息得到安全传输,但此种方式的缺点是:

    (1)不同的客户端、服务器数量庞大,所以双方都需要维护大量的密钥,维护成本很高

    (2)因每个客户端、服务器的安全级别不同,密钥极易泄露

    第二步:既然使用对称加密时,密钥维护这么繁琐,那我们就用非对称加密试试

    如上图所示,客户端用公钥对请求内容加密,服务器使用私钥对内容解密,反之亦然,但上述过程也存在缺点:

    (1)公钥是公开的(也就是黑客也会有公钥),所以第 ④ 步私钥加密的信息,如果被黑客截获,其可以使用公钥进行解密,获取其中的内容

    第三步:非对称加密既然也有缺陷,那我们就将对称加密,非对称加密两者结合起来,取其精华、去其糟粕,发挥两者的各自的优势

    如上图所示

    (1)第 ③ 步时,客户端说:(咱们后续回话采用对称加密吧,这是对称加密的算法和对称密钥)这段话用公钥进行加密,然后传给服务器

    (2)服务器收到信息后,用私钥解密,提取出对称加密算法和对称密钥后,服务器说:(好的)对称密钥加密

    (3)后续两者之间信息的传输就可以使用对称加密的方式了

    遇到的问题:

    (1)客户端如何获得公钥

    (2)如何确认服务器是真实的而不是黑客

    第四步:获取公钥与确认服务器身份

    1、获取公钥

    (1)提供一个下载公钥的地址,回话前让客户端去下载。(缺点:下载地址有可能是假的;客户端每次在回话前都先去下载公钥也很麻烦)

    (2)回话开始时,服务器把公钥发给客户端(缺点:黑客冒充服务器,发送给客户端假的公钥)

    2、那有木有一种方式既可以安全的获取公钥,又能防止黑客冒充呢? 那就需要用到终极武器了:SSL 证书(申购)

    如上图所示,在第 ② 步时服务器发送了一个SSL证书给客户端,SSL 证书中包含的具体内容有:

    (1)证书的发布机构CA

    (2)证书的有效期

    (3)公钥

    (4)证书所有者

    (5)签名

    ………

    3、客户端在接受到服务端发来的SSL证书时,会对证书的真伪进行校验,以浏览器为例说明如下:

    (1)首先浏览器读取证书中的证书所有者、有效期等信息进行一一校验

    (2)浏览器开始查找操作系统中已内置的受信任的证书发布机构CA,与服务器发来的证书中的颁发者CA比对,用于校验证书是否为合法机构颁发

    (3)如果找不到,浏览器就会报错,说明服务器发来的证书是不可信任的。

    (4)如果找到,那么浏览器就会从操作系统中取出 颁发者CA 的公钥,然后对服务器发来的证书里面的签名进行解密

    (5)浏览器使用相同的hash算法计算出服务器发来的证书的hash值,将这个计算的hash值与证书中签名做对比

    (6)对比结果一致,则证明服务器发来的证书合法,没有被冒充

    (7)此时浏览器就可以读取证书中的公钥,用于后续加密了

    4、所以通过发送SSL证书的形式,既解决了公钥获取问题,又解决了黑客冒充问题,一箭双雕,HTTPS加密过程也就此形成

    所以相比HTTP,HTTPS 传输更加安全

    (1) 所有信息都是加密传播,黑客无法窃听。

    (2) 具有校验机制,一旦被篡改,通信双方会立刻发现。

    (3) 配备身份证书,防止身份被冒充。

    总结

    综上所述,相比 HTTP 协议,HTTPS 协议增加了很多握手、加密解密等流程,虽然过程很复杂,但其可以保证数据传输的安全。所以在这个互联网膨胀的时代,其中隐藏着各种看不见的危机,为了保证数据的安全,维护网络稳定,建议大家多多推广HTTPS。

    HTTPS 缺点:

    (1)SSL 证书费用很高,以及其在服务器上的部署、更新维护非常繁琐

    (2)HTTPS 降低用户访问速度(多次握手)

    (3)网站改用HTTPS 以后,由HTTP 跳转到 HTTPS 的方式增加了用户访问耗时(多数网站采用302跳转)

    (4)HTTPS 涉及到的安全算法会消耗 CPU 资源,需要增加大量机器(https访问过程需要加解密)


    展开全文
  • WebAPI接口调试技巧

    千次阅读 2020-06-22 13:20:23
    1.了解WebAPI接口 接口模式:基于MVC4.0的WebAPI 承载协议:HTTP 跟踪工具:IE11 请求方式:POST 请求URL:IP:Port/Application/Controller/ActionName/Parameters 请求参数:一串由JSON对象转化而成的字符串 响应...

    1.了解WebAPI接口

    • 接口模式:基于MVC4.0的WebAPI
    • 承载协议:HTTP
    • 跟踪工具:IE11
    • 请求方式:POST
    • 请求URL:IP:Port/Application/Controller/ActionName/Parameters
    • 请求参数:一串由JSON对象转化而成的字符串
    • 响应状态:200(OK)
    • 响应结果: 一串JSON格式的数据
    • 响应类型:application/json

    2.WebAPI接口的URL规则

    • URL规则:IP:Port/Application/Controller/ActionName/Parameters
    • 示例:192.168.202.53/wszwdtapi_v6.6/taskkind/gettaskkindsbycodename
      IP:192.168.202.53,Port:80(默认)
      ApplicationName:wszwdtapi_v6.6
      Controller:taskkind
      ActionName:gettaskkindsbycodename
      Parameters:无

    3.HTTP请求模式

    • 两种最常用见的HTTP 请求方法:
      GET 和 POST
    • 标准版的利用方案:
      统一使用POST方式,为接口后台提供统一的参数处理规则。
    • 接口限制:接口会限制HTTP请求模式,如果限制了POST方式,则GET时会报404错误。
      | GET | POST |
      | ------------- |-------------|
      | 从指定的资源请求数据| 向指定的资源提交要被处理的数据 |
      | 参数必须以键值对的形式包含在URL中 | 建议参数以JSON字符串存放在请求体中 |
      | 请求体为空 | 利用请求体传数据 |

    4.HTTP状态消息

    • 常见的状态
      | 常见状态 | 注释 |
      | ------------- |-------------|
      | 200 OK | 请求成功 |
      | 304 Not Modified | 未按预期修改文档。 |
      | 403 Forbidden | 对被请求页面的访问被禁止。|
      | 404 Not Found | 服务器无法找到被请求的页面。|
      | 500 Internal Server Error | 请求未完成。服务器遇到不可预知的情况。|
      | 501 Not Implemented | 请求未完成。服务器不支持所请求的功能。|
      | 503 Service Unavailable | 请求未完成。服务器临时过载或当机。 |
      ####更多状态请点击这里

    5.常见的HTTP协议跟踪工具

    • IE/Chrome/FireFox等浏览器开发人员工具-网络工具
      (注:IE推荐使用10+,Chrome调试界面为英文)
    • Fildder(http://www.telerik.com/fiddler)
      Fildder基础原理
    • PostMan(Chrome插件) (https://www.getpostman.com/)

    6.科学的剖析接口调用情况

    • 当访问接口不成功,且初步排查没发现问题时,就应该先从HTTP请求入手,而不是耗费太多时间纠结在代码上。
    1. 打开调试工具,重复请求过程(刷新页面或重新点击提交按钮)
    2. 通过调试工具,查看是否存在对应的请求
    3. 如果不存在请求,现判断调用代码是否出现异常,有没有发出请求?
    4. 请求存在,判断请求状态码,顺藤摸瓜的分析原因。
      例如最常见错误,假如HTTP状态码为404,就可以通过判断IP、端口号,请求方式、URL字符串来确定是否是代码问题还是部署问题。
    5. 请求后得到状态码为200,那么再仔细研究下接口的传入数据和传出数据。
      ###7.使用Fiddler工具分析传入数据与返回数据
      ####使用Fiddler工具
    6. 打开Fiddler
    7. 利用浏览器访问对应的页面
    8. 在Fiddler左侧请求列表中,找对刚才的页面
    9. 点击选中,在Fiddler右侧查看详细数据。请求正文

    响应正文

    这里写图片描述
    ####利用Fiddler右侧Composer模拟请求

    1. 选择请求方式Get或者Post
    2. 输入URL
    3. 如果有参数,在Request Body中输入
    4. 点击Excute,发送请求
    5. 在右侧Log Requests中选择刚执行的请求
      Composer模拟请求

    8.常见问题的解决

    ####跨域问题

    • 当我们跟踪到带有关键字“Access-Control-Allow-Origin ”的错误时,说明我们遇到了跨域问题!如图:
      错误示例
      跨域问题的根本来自于浏览器的一个安全策略:同源策略
      所谓“同源”指的是“三个相同”:协议相同、域名相同、端口相同(IE浏览器下只需要满足协议及域名相同)
      如果非同源,共有三种行为受到限制。
    1. Cookie、LocalStorage 和 IndexDB 无法读取。
    2. DOM 无法获得。
    3. AJAX 请求不能发送。
    • 目前有三种方法规避这个限制。1.JSONP,2.WebSocket,3.CORS
      标准版统一采用CORS方式来规避同源策略。
    1. .Net中,在需要访问的接口的返回头中,加入“源信息”
      代码如下:HttpContext.Response.AppendHeader(“Access-Control-Allow-Origin”, “*”);
      或者在WebConfig中,为每个返回头加入“源信息”
    <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" /></customHeaders>
    

    ####常见的403错误

    • .Net模式的WebAPI的403错误,是一个典型的Web应用程序问题。
    • 现象:IP、端口完全正常,同台服务器部署的其他Web程序能正常访问,本接口在其他服务器上也能正常开放!根据状态码提示:该接口的应用程序本身存在问题。
      错误详情
    • 一般经验:.Net的WebAPI接口,是基于.Net的MVC框架,老版本IIS未必支持MVC机制,导致HTTP请求无法成功识别。一般情况将程序进程配置为集成模式即可。也有可能是因为未将.Net Framework4.0注册进IIS导致,通过命令注册即可。
    • 具体参考:http://blog.csdn.net/lingxyd_0/article/details/43154867
    • Unable To connect the Romote Server(无法连接到远程服务器)
    • 问题:Unable To connect the Romote Server(无法连接到远程服务器)
    • 分析:这两个问题,仍是接口不能访问导致的。问题表现形式较以往很大不同,是因为访问接口的不是JS代码,而是后台代码。
    • 结论:检查配置的接口地址是否正确,或者接口服务器是否开启。
    展开全文
  • vs2017开发web api 应用学习笔记

    千次阅读 2018-12-12 15:18:15
    参考网址:https://www.cnblogs.com/landeanfen/p/5337072.html,该文章对接口属性以及接口参数的传递有比较详细的描述。 一、新建web api 项目 在vs2017中选择新建项目-选择asp.net web 应用程序,在如下图示...

    参考网址:https://www.cnblogs.com/landeanfen/p/5337072.html,该文章对接口属性以及接口参数的传递有比较详细的描述。

    一、新建web api 项目

    在vs2017中选择新建项目-选择asp.net  web 应用程序,在如下图示项目选择窗口中,选择“空“项目,勾选 Web Api,确定后系统自动创建空的Web Api项目;

    二、设置路由

    默认情况下创建的Web Api 项目采用"api/{controller}/{id}" 的方式映射访问路由,即:api为默认路径前缀,controller对应为控制器名称中去掉controller中的部分,而接口名称采用get前缀的方法,即访问接口的method采用get,其它的依次类推,访问接口非常的机械且难以理解,可在控制器中使用RoutePrefix属性重新定义控制对应的访问路径名称,在方法中使用Route属性映射方法的访问路径,使用HttpGet等属性映射方法的访问method,这样可提高整个应用的灵活性和规范性;

    三、在web api中启用会话支持

    web api默认情况并不支持会话,通过 HttpContext.Current.Session访问相关会话对象时,总是为null,需要使用以下方法启用会话支持:

    重写global.asax对象对的  Init() 方法,示例代码如下:
        

     public override void Init()
            {
                //=======================启用会话=============================
                this.PostAuthenticateRequest += (sender, e) => HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
                base.Init();
            }

    四、对接口启用访问认证

    新建RequestAuthorizeAttribute类,该类继承至AuthorizeAttribute,重写父类的OnAuthorization方法;在需要验证的接口方法中使用RequestAuthorizeAttribute属性,RequestAuthorizeAttribute代码如下:

     public class RequestAuthorizeAttribute : AuthorizeAttribute
        {
            public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
            {
                //从http请求的头里面获取身份验证信息,验证是否是请求发起方的ticket
                var authorization = actionContext.Request.Headers.Authorization;
                if ((authorization != null) && (authorization.Parameter != null))
                {
                    //解密用户ticket,并校验用户名密码是否匹配
                    var encryptTicket = authorization.Parameter;
                    if (ValidateTicket(encryptTicket))
                    {
                        base.IsAuthorized(actionContext);
                    }
                    else
                    {
                        HandleUnauthorizedRequest(actionContext);
                    }
                }
                //如果取不到身份验证信息,并且不允许匿名访问,则返回未验证401
                else
                {
                    var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
                    bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);
                    if (isAnonymous) base.OnAuthorization(actionContext);
                    else HandleUnauthorizedRequest(actionContext);
                }
            }
    
            //校验用户名密码(正式环境中应该是数据库校验)
            private bool ValidateTicket(string encryptTicket)
            {
                //解密Ticket
                var strTicket = FormsAuthentication.Decrypt(encryptTicket).UserData;
    
                //从Ticket里面获取用户名和密码
                var index = strTicket.IndexOf("&");
                string strUser = strTicket.Substring(0, index);
                string strPwd = strTicket.Substring(index + 1);
    
                if (strUser == "test" && strPwd == "123456")
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

    接口启用验证的示例代码如下:

            [HttpPut]
            [RequestAuthorize]
            [Route("update/{id}")]
            public LoginToken update(string id,[FromBody] Logins login)
            {
                System.Diagnostics.Debug.WriteLine(login);
    
                LoginToken token = new LoginToken { token = "1111111111", userId = "test", userName = "test" };
                return token;
            }

    五、webApi接口参数

    1、接口调用方式:webap有put、get、delete、post等集中调用方式,在未显示说明接口调用方式属性时,对Get开始的方法默认为采用get方式(post、put、delete类似),若接口方法默认不符合约定,则需要使用属性明确说明;

    2、对get方法可适用[Fromuri] 参数,说明接口参数来自于url,而post、put、delete方法可采用[frombody]属性将来自于http数据部分的数据序列化为指定对的对象的类型,当不明确来自于数据部分的对象类型,对接口参数采用dynamic类型是不错的选择,示例如下:

    前端提交的数据内容:

       $.ajax({
            type: "post",
            url: "http://localhost:27221/api/Charging/SaveData",
            contentType: 'application/json',
            data: JSON.stringify({ NAME: "Jim",DES:"备注" }),
            success: function (data, status) {}
        });

    后端数据接口:

            [HttpPost]
            public object SaveData(dynamic obj)
            {
                var strName = Convert.ToString(obj.NAME);
                return strName;
            }

    需要注意的是:若需要dynamic对象直接序列化为对象,需要在前端提交数据的时候,将数据用JSON.stringfy(data)序列化为json对象,否则后端得到的是层层嵌套的对象;

    3、接口采用对象,如下示例接口:

    [HttpPost]
            public bool SaveData(TB_CHARGING oData)
            {
                return true;
            }

    同上:明确采用json格式进行数据传递时,需要用JSON.stringfy(data)序列化为json对象

    对接口传递数组对象时,可采用List<ObjectType>的类型传递接口参数,示例如下:

     [HttpPost]
            public bool SaveData(List<TB_CHARGING> lstCharging)
            {
                return true;
            }

    六、利用webApi上传文件

    前端需要content-type信息为:

    "Content-Type":"multipart/form-data"

    后端代码如下示例:

    HttpRequest httpRequest = HttpContext.Current.Request;
                foreach (string file in httpRequest.Files)
                {
                    System.Diagnostics.Debug.WriteLine(httpRequest.Files[file].FileName);
                    System.IO.Stream inStream = httpRequest.Files[file].InputStream;
                    byte[] buffer = new byte[inStream.Length];
                    inStream.Read(buffer, 0, buffer.Length);
                    
                    var filePath = HttpContext.Current.Server.MapPath("~/" + httpRequest.Files[file].FileName);
                    httpRequest.Files[file].SaveAs(filePath);
                }

     

    展开全文
  • Web API数据传输加密

    万次阅读 2015-08-18 12:03:12
    1、Web API接口访问分类 Web API接口访问方式,大概可以分为几类: 1)一个是使用用户令牌,通过Web API接口进行数据访问。这种方式,可以有效识别用户的身份,为用户接口返回用户相关的数据,如包括用户...

    1、Web API的接口访问分类

    Web API接口的访问方式,大概可以分为几类:

    1)一个是使用用户令牌,通过Web API接口进行数据访问。这种方式,可以有效识别用户的身份,为用户接口返回用户相关的数据,如包括用户信息维护、密码修改、或者用户联系人等与用户身份相关的数据。

    2)一种是使用安全签名进行数据提交。这种方式提交的数据,URL连接的签名参数是经过安全一定规则的加密的,服务器收到数据后也经过同样规则的安全加密,确认数据没有被中途篡改后,再进行数据修改处理。因此我们可以为不同接入方式,如Web/APP/Winfrom等不同接入方式指定不同的加密秘钥,但是秘钥是双方约定的,并不在网络连接上传输,连接传输的一般是这个接入的AppID,服务器通过这个AppID来进行签名参数的加密对比,这种方式,类似微信后台的回调处理机制,它们就是经过这样的处理。

    3)一种方式是提供公开的接口调用,不需要传入用户令牌、或者对参数进行加密签名的,这种接口一般较少,只是提供一些很常规的数据显示而已。

    下面图示就是这几种接入方式的说明和大概应用场景。

     

    2、Web API使用安全签名的实现

    首先我们为用户注册的时候,需要由我们认可的终端发起,也就是它们需要进行安全签名,后台确认签名有效性,才能正常实现用户注册,否则遭到伪造数据,系统就失去原有的意义了。

    复制代码
        /// <summary>
        /// 注册用户信息接口
        /// </summary>
        public interface IUserApi
        {
            /// <summary>
            /// 注册用户处理,包括用户名,密码,身份证号,手机等信息
            /// </summary>
            /// <param name="json">注册用户信息</param>
            /// <param name="signature">加密签名字符串</param>
            /// <param name="timestamp">时间戳</param>
            /// <param name="nonce">随机数</param>
            /// <param name="appid">应用接入ID</param>
            /// <returns></returns>
            ResultData Add(UserJson json,
                string signature, string timestamp, string nonce, string appid);
        }
    复制代码

    其实我们获得用户的令牌,也是需要进行用户安全签名认证的,这样我们才有效保证用户身份令牌获取的合法性。

    复制代码
        /// <summary>
        /// 系统认证等基础接口
        /// </summary>
        public interface IAuthApi
        {
            /// <summary>
            /// 注册用户获取访问令牌接口
            /// </summary>
            /// <param name="username">用户登录名称</param>
            /// <param name="password">用户密码</param>
            /// <param name="signature">加密签名字符串</param>
            /// <param name="timestamp">时间戳</param>
            /// <param name="nonce">随机数</param>
            /// <param name="appid">应用接入ID</param>
            /// <returns></returns>
            TokenResult GetAccessToken(string username, string password,
                string signature, string timestamp, string nonce, string appid);
        }
    复制代码

    上面介绍到的参数,我们提及了几个参数,一个是加密签名字符串,一个是时间戳,一个是随机数,一个是应用接入ID,我们一般的处理规则如下所示。

    1)Web API 为各种应用接入,如APP、Web、Winform等接入端分配应用AppID以及通信密钥AppSecret,双方各自存储。
    2)接入端在请求Web API接口时需携带以下参数:signature、 timestamp、nonce、appid,签名是根据几个参数和加密秘钥生成。
    3) Web API 收到接口调用请求时需先检查传递的签名是否合法,验证后才调用相关接口。

    加密签名在服务端(Web API端)的验证流程参考微信的接口的处理方式,处理逻辑如下所示。

    1)检查timestamp 与系统时间是否相差在合理时间内,如10分钟。
    2)将appSecret、timestamp、nonce三个参数进行字典序排序
    3)将三个参数字符串拼接成一个字符串进行SHA1加密
    4)加密后的字符串可与signature对比,若匹配则标识该次请求来源于某应用端,请求是合法的。

    C#端代码校验如下所示。

    复制代码
            /// <summary>
            /// 检查应用接入的数据完整性
            /// </summary>
            /// <param name="signature">加密签名内容</param>
            /// <param name="timestamp">时间戳</param>
            /// <param name="nonce">随机字符串</param>
            /// <param name="appid">应用接入Id</param>
            /// <returns></returns>
            public CheckResult ValidateSignature(string signature, string timestamp, string nonce, string appid)
            {
                CheckResult result = new CheckResult();
                result.errmsg = "数据完整性检查不通过";
    
                //根据Appid获取接入渠道的详细信息
                AppInfo channelInfo = BLLFactory<App>.Instance.FindByAppId(appid);
                if (channelInfo != null)
                {
                    #region 校验签名参数的来源是否正确
                    string[] ArrTmp = { channelInfo.AppSecret, timestamp, nonce };
    
                    Array.Sort(ArrTmp);
                    string tmpStr = string.Join("", ArrTmp);
    
                    tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
                    tmpStr = tmpStr.ToLower();
    
                    if (tmpStr == signature && ValidateUtil.IsNumber(timestamp))
                    {
                        DateTime dtTime = timestamp.ToInt32().IntToDateTime();
                        double minutes = DateTime.Now.Subtract(dtTime).TotalMinutes;
                        if (minutes > timspanExpiredMinutes)
                        {
                            result.errmsg = "签名时间戳失效";
                        }
                        else
                        {
                            result.errmsg = "";
                            result.success = true;
                            result.channel = channelInfo.Channel;
                        }
                    }
                    #endregion
                }
                return result;
            }
    复制代码

    一旦我们完成对安全签名进行成功认证,也就是我们对数据提交的来源和完整性进行了确认,就可以进行更多和安全性相关的操作了,如获取用户的访问令牌信息的操作如下所示。

    第一步是验证用户的签名是否符合要求,符合要求后进行用户信息的比对,并生成用户访问令牌数据JSON,返回给调用端即可。

     

    3、Web API使用安全令牌的实现

    通过上面的接口,我们获取到的用户访问令牌,以后和用户相关的信息调用,我们就可以通过这个令牌参数进行传递就可以了,这个令牌带有用户的一些基础信息,如用户ID,过期时间等等,这个Token的设计思路来源于JSON Web Token (JWT),具体可以参考http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html,以及GitHub上的项目https://github.com/jwt-dotnet/jwt

    由于Web API的调用,都是一种无状态方式的调用方式,我们通过token来传递我们的用户信息,这样我们只需要验证Token就可以了。

    JWT的令牌生成逻辑如下所示

    令牌生成后,我们需要在Web API调用处理前,对令牌进行校验,确保令牌是正确有效的。

    检查的代码,就是把令牌生成的过程逆反过来,获取相应的信息,并且对令牌签发的时间进行有效性判断,一般可以约定一个失效时间,如1天或者7天,也不用设置太短。

    复制代码
            /// <summary>
            /// 检查用户的Token有效性
            /// </summary>
            /// <param name="token"></param>
            /// <returns></returns>
            public CheckResult ValidateToken(string token)
            {
                //返回的结果对象
                CheckResult result = new CheckResult();
                result.errmsg = "令牌检查不通过";
    
                if (!string.IsNullOrEmpty(token))
                {
                    try
                    {
                        string decodedJwt = JsonWebToken.Decode(token, sharedKey);
                        if (!string.IsNullOrEmpty(decodedJwt))
                        {
                            #region 检查令牌对象内容
                            dynamic root = JObject.Parse(decodedJwt);
                            string username = root.name;
                            string userid = root.iss;
                            int jwtcreated = (int)root.iat;
    
                            //检查令牌的有效期,7天内有效
                            TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
                            int timestamp = (int)t.TotalDays;
                            if (timestamp - jwtcreated > expiredDays)
                            {
                                throw new ArgumentException("用户令牌失效.");
                            }
    
                            //成功校验
                            result.success = true;
                            result.errmsg = "";
                            result.userid = userid;
                            #endregion
                        }
                    }
                    catch (Exception ex)
                    {
                        LogTextHelper.Error(ex);
                    }
                }
                return result;
            }
    复制代码

    一般来说,访问令牌不能永久有效,对于访问令牌的重新更新问题,可以设置一个规则,只允许最新的令牌使用,并把它存储在接口缓存里面进行对比,应用系统退出的时候,就把内存里面的Token移除就可以了。

    4、ASP.NET Web API的开发

     上面我们定义了一般的Web API接口,以及实现相应的业务实现,如果我们需要创建Web API层,还需要构建一个Web API项目的。

    创建好相应的项目后,可以为项目添加一个Web API基类,方便控制共同的接口。

    然后我们就可以在Controller目录上创建更多的应用API控制器了。

    最后我们为了统一所有的API接口都是返回JSON方式,我们需要对WebApiConfig里面的代码进行设置下。

    复制代码
        public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                // Web API 配置和服务
                config.SetCorsPolicyProviderFactory(new CorsPolicyFactory());
                config.EnableCors();
    
                // Web API 路由
                config.MapHttpAttributeRoutes();
    
                config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{action}/{id}",
                    defaults: new { action = "post", id = RouteParameter.Optional }
                );
    
                // Remove the JSON formatter
                //config.Formatters.Remove(config.Formatters.JsonFormatter);
    
                // Remove the XML formatter
                config.Formatters.Remove(config.Formatters.XmlFormatter);
            }
        }
    复制代码

    5、Web API 接口的测试

    接下来我们要做的就是需要增加业务接口,以便进行具体的测试了,建议使用Winform项目,对每个接口进行一个测试,或者也可以考虑使用单元测试的方式,看个人喜好吧。

    例如我们如果要测试用户登陆的接口的话,我们的测试代码如下所示。

    复制代码
            /// <summary>
            /// 生成签名字符串
            /// </summary>
            /// <param name="appSecret">接入秘钥</param>
            /// <param name="timestamp">时间戳</param>
            /// <param name="nonce">随机数</param>
            private string SignatureString(string appSecret, string timestamp, string nonce)
            {
                string[] ArrTmp = { appSecret, timestamp, nonce };
    
                Array.Sort(ArrTmp);
                string tmpStr = string.Join("", ArrTmp);
    
                tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
                return tmpStr.ToLower();
            }
    
            private TokenResult GetTokenResult()
            {
                string timestamp = DateTime.Now.DateTimeToInt().ToString();
                string nonce = new Random().NextDouble().ToString();
                string signature = SignatureString(appSecret, timestamp, nonce);
    
                string appended = string.Format("&signature={0}&timestamp={1}&nonce={2}&appid={3}", signature, timestamp, nonce, appId);
                string queryUrl = url + "Auth/GetAccessToken?username=test&password=123456" + appended;
    
                HttpHelper helper = new HttpHelper();
                string token = helper.GetHtml(queryUrl);
                Console.WriteLine(token);
                TokenResult tokenResult = JsonConvert.DeserializeObject<TokenResult>(token);
                return tokenResult;
            }
    复制代码

    如果我们已经获得了令牌,我们根据令牌传递参数给连接,并获取其他数据的测试处理代码如下所示。

    复制代码
                //获取访问令牌
                TokenResult tokenResult = GetTokenResult();
    
                string queryUrl = url + "/Contact/get?token=" + tokenResult.access_token;
                HttpHelper helper = new HttpHelper();
                string result = helper.GetHtml(queryUrl);
                Console.WriteLine(result);
    复制代码

    如果需要POST数据的话,那么调用代码如下所示。

    复制代码
                //使用POST方式
                var data = new
                {
                    name = "张三",
                    certno = "123456789",
                };
                var postData = data.ToJson();
    
                queryUrl = url + "/Contact/Add?token=" + tokenResult.access_token;
                helper = new HttpHelper();
                helper.ContentType = "application/json";
                result = helper.GetHtml(queryUrl, postData, true);
                Console.WriteLine(result);
    复制代码

    Web API后台,会自动把POST的JSON数据转换为对应的对象的。

    如果是GET方式,我们可能可以直接通过浏览器进行调试,如果是POST方式,我们需要使用一些协助工具,如Fiddler等处理工具,但是最好的方式是自己根据需要弄一个测试工具,方便测试。

    以下就是我为了自己Web API 接口开发的需要,专门弄的一个调试工具,可以自动组装相关的参数,包括使用安全签名的参数,还可以把所有参数数据进行存储。

    转载自:点击打开链接

    展开全文
  • ASP.NET 使用Swagger开发Web API接口项目

    千次阅读 2018-05-15 15:12:47
    ASP.NET 使用Swagger开发WebApi接口项目:项目使用Web API创建自动提供了API文档,采用mvc方式创建项目稍麻烦点需要手动添加WebApiConfig配置,而采用Web API项目这些都已经生成好了。创建Web API项目添加Swagger...
  • 《Asp.Net Web API》-----webApi的简单使用

    万次阅读 多人点赞 2016-09-29 16:16:08
    前言:在公司工作的时候,经理跟我说我们后台用的是WebApi技术,说它是一种轻量级的WCF,我以前用过WCF,但是对于WebApi有点不熟悉,但是经理说和WCF相似,我渐渐的对着门技术变得渐渐的好奇起来,下面由小编带领着...
  • ASP.NET MVC同时支持web与webapi模式

    千次阅读 2017-03-23 16:19:21
    我们在创建 web mvc项目时是不支持web api接口方式访问的,所以我们需要添加额外的组件来支持实现双模式。 首先我们需要准备三个web api依赖的组件(目前在.net 4/4.5版本下面测试正常,2.0暂未进行测试,需要...
  • API接口安全

    万次阅读 2017-08-08 14:20:41
    API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。...
  • 需求:提供高德地图搜索地点功能,并查出经纬度坐标。...地点详情接口: http://restapi.amap.com/v3/assistant/inputtips?output=xml&city=010&keywords=招商银行&key=<用户的key>使用说明第一步,申
  • C# WebAPI创建及具体实现

    千次阅读 2018-11-22 22:41:47
    Web API 其实就是应用程序编程接口,在实际的生活中,我们使用的软件有很多都是从API中获取的数据,比如:天气预报,微信支付等都是使用的接口,这样我们在编程过程中就可以使用别人已经写好的接口,可以省很多时间...
  • Java的API接口实现例子

    万次阅读 2019-05-28 14:20:02
    java发一个http请求过去,带上参数就可以了,跟我们在浏览器上访问资源是一样的 只是它返回的是json格式的数据而已。 比如以下有两个方法: public static String do_post(String url, List<NameValuePair> ...
  • WebApi发布到外网提示404问题

    千次阅读 2017-07-11 13:44:19
    今天在做微信接口的对接,需要把webApi发布到服务器,放上去的时候,提示404 找了以后,发现了这段代码,粘贴上去就可以用了在web.config添加如下节点 <system.webServer> </modu
  • apiDebug-API接口调试插件,开源API接口调试插件,Restfull接口调试软件,Restfull接口调试插件,谷歌API接口调试插件,Chrome浏览器接口调试插件,POST请求模拟插件,api接口调试工具,开源接口调试工具,POST模拟...
  • 用户登录及API接口设计

    万次阅读 2018-12-11 14:06:40
    comments ...1、如果是web分离开发秘钥可以采用非对称加密; 2、安全性上面采用https(Ps:在安全性要求不是非常严格的情况下,不用TLS的“安全”,都是掩耳盗铃) ------------------------------...
  • MVC搭建webAPI服务

    千次阅读 2018-06-28 12:03:35
    近期,有小伙伴再微信公众号中不断刷新SpringBoot的搭建过程,...详情可以参见https://blog.csdn.net/qq_28135179/article/details/80685924。完全是入门SpringBoot的绝世好帖。 本人是学习C#的,重心依然放在C#这...
  • 百度的 web.config中加入 ``` *" /> , POST, PUT, DELETE, OPTIONS" /> ``` 没用。 Microsoft.AspNet.WebApi.Cors 包好像兼容不了 也用不了
  • vSphere API 是作为一种语言无关的 Web 服务实现的,它基于一个远程过程调用机制,客户端应用程序使用它来访问 ESXi和 vCenter 服务器系统上的服务和组件。本章节主要包括以下内容: ■ vSphere Client-Server 架构 ...
  • API Restful接口开发 版本控制

    千次阅读 2019-12-05 15:23:23
    API版本控制常用实践 ** URL:http://example.com/v1/helloworld HEADER: 各大公司做法: http://www.lexicalscope.com/blog/2012/03/12/how-are-rest-apis-versioned/ Spring Boot实践API版本管理 原理...
  • WebAPI实现跨域请求

    万次阅读 热门讨论 2018-05-20 21:04:14
    一、跨域问题的由来 目前项目实现前后端分离,所以就会那么此时前端和后端分别在...2.前后端分离:现在我们的积分系统前端采用angular,后端采用webapi,所以整个系统是部署在不同的小项目中的,此时我们称之为前...
  • 获得WebAPI原始POST请求BODY的JSON内容

    万次阅读 2017-09-21 09:24:57
    在controller的action里写如下代码: string content = Request.Content.ReadAsStringAsync().Result; 但是这段代码获取的content却是空的,搞了半天没明白,后来在一个国外的论坛找到了原因。...
1 2 3 4 5 ... 20
收藏数 122,135
精华内容 48,854
热门标签
关键字:

webapi 访问https接口