在我的混合式开发框架里面,集成了WebAPI的访问,这种访问方式不仅可以实现简便的数据交换,而且可以在多种平台上进行接入,如Winform程序、Web网站、移动端APP等多种接入方式,Web API的处理方式和微信提供的接口处理规则类似,也是通过向服务器获得访问令牌(AccessToken),然后传递给每个Web API接口,实现数据的交换处理。本篇随笔主要介绍混合框架中Winform对Web API访问的处理。

1、Web API接入方式介绍

《混合式开发框架》混合了Web API接口访问、WCF接口访问,以及直接访问数据库三种方式的接入,以适应多种场景的应用,是基于门面层的一种接口实现处理和封装。是一种弹性化非常好的框架应用,既可用于单机版软件或者基于局域网内的应用软件,也可以用于分布式技术的互联网环境应用,是一种成熟稳定、安全高效的技术框架。

关于这个框架的详细介绍,可以查看我的随笔《Winform混合式开发框架的特点总结》进行详细了解。

这里主要关注Web API的接入方式,我们知道,如果是一般的接口,如果公布在互联网上面,就会有很多接入的风险,因此需要对接口的调用进行检查校验,确保访问令牌有效,而且对数据发生修改的,还需要对数据的加密签名进行检查,才能保证我们的接口运行在较为安全的环境中。

混合框架调用Web API接口的详细过程,可以通过《Web API应用架构在Winform混合框架中的应用(3)--Winfrom界面调用WebAPI的过程分解》、《Web API应用架构在Winform混合框架中的应用(1)》、《Web API接口设计经验总结》进行了解。

2、Web API的接口访问令牌的处理

由于我们需要对接口访问的身份进行核实,因此一般要求我们的接口都带有一个token参数,用来对用户身份进行识别,如下所示是Web API层的MVC控制器的接口定义。

  1. [HttpGet]
  2. public UserInfo GetUserByName(string userName, string token)
  3. {
  4. //令牌检查,不通过则抛出异常
  5. CheckResult checkResult = CheckToken(token);
  6.  
  7. return BLLFactory<User>.Instance.GetUserByName(userName);
  8. }

如果我们在客户端需要调用这个接口,那么就需要传入这个token参数,也就是说这个token令牌需要在调用任何接口前获得,这样才能为我们后面的接口调用做好准备。

而这个token的产生是非常重要的,需要严格颁发,因此需要对获取这个token的方法的参数进行签名校验,如下面代码是WebAPI接口对产生token的处理。

  1. /// <summary>
  2. /// 注册用户获取访问令牌接口
  3. /// </summary>
  4. /// <param name="username">用户登录名称</param>
  5. /// <param name="password">用户密码</param>
  6. /// <param name="signature">加密签名字符串</param>
  7. /// <param name="timestamp">时间戳</param>
  8. /// <param name="nonce">随机数</param>
  9. /// <param name="appid">应用接入ID</param>
  10. [HttpGet]
  11. public TokenResult GetAccessToken(string username, string password, string signature, string timestamp, string nonce, string appid)

也就是需要传入用户名、密码、加密签名、时间戳、随机数、应用接入ID等信息,从而构建出来一个访问令牌,通过用户名、密码、加密签名校验等方式,可以实现对访问令牌(token)的严格颁发处理。

在客户端调用所有Web API接口前,我们需要先通过上面的Web API接口,获取到该用户的访问令牌,为了方便,我们可以在客户端封装一个函数,通过这个函数获取到对应的访问令牌,然后把它存储在缓存里面,方便各个模块的接口访问处理。

  1. /// <summary>
  2. /// 用户获取令牌的辅助类
  3. /// </summary>
  4. public class AccessTokenHelper
  5. {
  6. private const string APPID = "APPID";//应用ID,由系统管理员分配
  7. private const string APPSECRET = "APPSECRET";//应用秘钥,,由系统管理员分配
  8. private const string DEFAULT_API_URL = "http://localhost:9001/api/Auth/GetAccessToken";//默认调试的Web API获取授权地址
  9.  
  10. /// <summary>
  11. /// 设置签名参数。
  12. /// 由于Web API大多数的接口,都需要验证用户身份的访问令牌(accesstoken),因此用户在登陆的时候,需要使用这个步骤去获取令牌信息,然后在继续后续的接口操作。
  13. /// 该接口用到的应用ID、应用秘钥等参数,由系统管理员统一分配。
  14. /// </summary>
  15. public static bool GetAccessToken(string username, string password)
  16. {
  17. bool result = false;
  18.  
  19. //配置使用Web API模式,需要构建登陆token才能访问
  20. AppConfig config = new AppConfig();
  21. string callerType = config.AppConfigGet("CallerType");
  22. string apiUrl = config.AppConfigGet("AuthApiUrl");
  23. apiUrl = string.IsNullOrEmpty(apiUrl) ? DEFAULT_API_URL : apiUrl;
  24.  
  25. if (callerType.Equals("api", StringComparison.OrdinalIgnoreCase))
  26. {
  27. //使用API方式,需要在缓存里面设置特殊的信息
  28. var url = apiUrl + SignatureHelper.GetSignatureUrl(APPID, APPSECRET);
  29. url += string.Format("&username={0}&password={1}", username, password);
  30.  
  31. TokenResult tokenResult = JsonHelper<TokenResult>.ConvertJson(url);
  32. result = !string.IsNullOrEmpty(tokenResult.access_token);
  33.  
  34. if (tokenResult == null)
  35. {
  36. var message = "获取授权信息出错,请检查地址是否正确!";
  37. MessageDxUtil.ShowError(message);
  38. }
  39.  
  40. var SignatureInfo = new SignatureInfo()
  41. {
  42. appid = APPID,
  43. appsecret = APPSECRET,
  44. token = (tokenResult != null) ? tokenResult.access_token : null
  45. };
  46. Cache.Instance.Add("SignatureInfo", SignatureInfo);
  47. }
  48.  
  49. return result;
  50. }

有了这个辅助方法,我们可以在程序启动后,用户进行身份登录的时候,先调用这个方法来获取令牌。

  1. string ip = NetworkUtil.GetLocalIP();
  2. string macAddr = HardwareInfoHelper.GetMacAddress();
  3. string loginName = this.txtLoginName.Text.Trim();
  4. string password = this.txtPassword.Text;
  5.  
  6. //如果无法获取访问令牌,则返回
  7. bool hasGotToken = AccessTokenHelper.GetAccessToken(loginName, password);
  8. if (!hasGotToken)
  9. {
  10. return;
  11. }

刚才我提到了Web API层的MVC控制器的接口定义,默认后面一般都有一个token参数,如下代码所示

  1. [HttpGet]
  2. public UserInfo GetUserByName(string userName, string token)
  3. {
  4. //令牌检查,不通过则抛出异常
  5. CheckResult checkResult = CheckToken(token);
  6.  
  7. return BLLFactory<User>.Instance.GetUserByName(userName);
  8. }

而我们为了方便客户端调用,一般在客户端调用Web API的时候进行简化了一下,把token参数拿掉,它的值从缓存里面提取。如客户端调用的封装代码如下所示。

  1. public UserInfo GetUserByName(string userName)
  2. {
  3. var action = "GetUserByName";
  4. string url = GetTokenUrl(action) + string.Format("&userName={0}", userName);
  5.  
  6. UserInfo result = JsonHelper<UserInfo>.ConvertJson(url);
  7. return result;
  8. }

其中GetTokenUrl就是我们根据token和方法名称,构建一个连接字符串,函数实现如下所示。

  1. /// <summary>
  2. /// 获取单纯包含token参数的连接
  3. /// </summary>
  4. /// <param name="action">控制器方法名称</param>
  5. /// <returns></returns>
  6. protected string GetTokenUrl(string action)
  7. {
  8. string url = "";
  9. if (this.SignatureInfo != null)
  10. {
  11. var append = string.Format("?token={0}", SignatureInfo.token);
  12.  
  13. string baseUrl = GetBaseUrl();
  14. url = CombindUrl(baseUrl, action + append);//组合为完整的访问地址
  15. }
  16. else
  17. {
  18. throw new ArgumentNullException("没有在缓存里面设置SignatureInfo签名信息");
  19. }
  20. return url;
  21. }

这样最终我们可以获得类似下面的连接地址:

  1. http://localhost:27206/api/Account/GetAccountTypeList?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIxIiwiaWF0IjoxNDYzNTU3OTAzLCJqdGkiOiI3OGMyOGRhNC01ZjRjLTQxYzItOThkNC1lYmFkZTM3YjA4NjUiLCJuYW1lIjoiYWRtaW4iLCJjaGFubmVsIjoiMCIsInNoYXJlZGtleSI6IjEyMzRhYmNkIn0.DysdbGx70xuIxXBz3G3x3MkGh9ZxL2zF9Fzu8FGVS0w

有了这个令牌组装好的URL,我们可以对访问结果的JSON字符串进行解析,把它解析为对应的数据就可以了。

当然,在实际的Web API接口开发过程中,我们还可以使用Web API工具进行接口调试,如下所示。

下面的1-5的标识就是获取token所需要的签名数据,当然连接还带有几个账号认证所需要的信息了,如账号密码、所在公司等信息。

当然我们也可以使用浏览器进行测试获取Token的信息,只是没有那么方便而已。

Winform混合式开发框架访问Web API接口的处理的更多相关文章

  1. 如何让你的 Asp.Net Web Api 接口,拥抱支持跨域访问。

    由于 web api 项目通常是被做成了一个独立站点,来提供数据,在做web api 项目的时候,不免前端会遇到跨域访问接口的问题. 刚开始没做任何处理,用jsonp的方式调用 web api 接口, ...

  2. Asp.Net Web Api 接口,拥抱支持跨域访问。

    如何让你的 Asp.Net Web Api 接口,拥抱支持跨域访问. 由于 web api 项目通常是被做成了一个独立站点,来提供数据,在做web api 项目的时候,不免前端会遇到跨域访问接口的问题 ...

  3. Winform混合式开发框架的特点总结

    Winform混合式开发框架,是一种支持分布式部署的应用模式,支持直接连接数据库,访问远程WCF服务,访问远程Web API服务等服务的综合性框架,根据不同的需求采用不同的数据接口,是一个适应性很广的 ...

  4. Web API接口设计经验总结

    在Web API接口的开发过程中,我们可能会碰到各种各样的问题,我在前面两篇随笔<Web API应用架构在Winform混合框架中的应用(1)>.<Web API应用架构在Winfo ...

  5. Web API接口 安全验证

    在上篇随笔<Web API应用架构设计分析(1)>,我对Web API的各种应用架构进行了概括性的分析和设计,Web API 是一种应用接口框架,它能够构建HTTP服务以支撑更广泛的客户端 ...

  6. Web API接口设计(学习)

    1.在接口定义中确定MVC的GET或者POST方式 由于我们整个Web API平台是基于MVC的基础上进行的API开发,因此整个Web API的接口,在定义的时候,一般需要显示来声明接口是[HttpG ...

  7. Http下的各种操作类.WebApi系列~通过HttpClient来调用Web Api接口

    1.WebApi系列~通过HttpClient来调用Web Api接口 http://www.cnblogs.com/lori/p/4045413.html HttpClient使用详解(java版本 ...

  8. Asp.Net Web Api 接口

    如何让你的 Asp.Net Web Api 接口,拥抱支持跨域访问.   由于 web api 项目通常是被做成了一个独立站点,来提供数据,在做web api 项目的时候,不免前端会遇到跨域访问接口的 ...

  9. 整合微信小程序的Web API接口层的架构设计

    在我前面有很多篇随笔介绍了Web API 接口层的架构设计,以及对微信公众号.企业号.小程序等模块的分类划分.例如在<C#开发微信门户及应用(43)--微信各个项目模块的定义和相互关系>介 ...

随机推荐

  1. 嵌入式的重要平台 .NET Micro Framework

    曾经辉煌的巨人PC界渐渐走向下坡路,而智能手机圈则没完没了般地争个你死我活.随着智能手机的广泛普及,不少商家为了不坐以待毙而纷纷开始涉足与穿戴式设备--智能手表(具体参见智能手表时代还有多远). 我们 ...

  2. 收集最好的Mac软件和使用方法

    MacBook 初体验 作者是刚从Windows下转到mac时写的,这篇文章对也主要介绍了Mac下开发环境的部署.软件的安装和卸载.常用快捷键.文件系统的介绍. http://liujiacai.ne ...

  3. New Year's resolution for 2016

    A New Year's resolution is a traditional for me to celebrate a new beginning. For the past year, I h ...

  4. 60分钟Python快速学习(给发哥一个交代)

    60分钟Python快速学习 之前和同事谈到Python,每次下班后跑步都是在听他说,例如Python属于“胶水语言啦”,属于“解释型语言啦!”,是“面向对象的语言啦!”,另外没有数据类型,逻辑全靠空 ...

  5. 实现 Math.Asin 迈克劳林(泰勒)展开式,结果比Math.Asin 慢一倍

    项目中需要快速求解Asin(x) 的近似值,原以为用泰勒展开式会快一些,结果比原生的慢一倍. Math.ASin        Time Elapsed:   9ms        Gen 0:    ...

  6. 支持向量机(SVM)复习总结

    摘要: 1.算法概述 2.算法推导 3.算法特性及优缺点 4.注意事项 5.实现和具体例子 6.适用场合 内容: 1.算法概述 其基本模型定义为特征空间上的间隔最大的线性分类器,即支持向量机的学习策略 ...

  7. Swift语言快速入门

    Swift语言快速入门(首部同步新版官方API文档和语法的Swift图书,确保代码可编译,作者专家在线答疑,图书勘误实时跟进) 极客学院 编著   ISBN 978-7-121-24328-8 201 ...

  8. Azure Service Febric 笔记:Web API应用

    1.什么是Service Febric 贴一段微软官方的介绍 Service Fabric 是一种分布式系统平台,可让你轻松打包.部署和管理可缩放.可靠的微服务.Service Fabric 还解决了 ...

  9. Discuz门户首页关键词和描述显示“首页”的解决方法

    Discuz社区在后台设置好门户标题.关键字.描述,更新缓存,发现用户登录状态下,门户首页的关键字和描述正常显示:但在游客状态下不显示,在某工具中查看到的情况如下: 现找到两种解决办法:(记得修改前备 ...

  10. Entity Framework Code First添加修改及删除单独实体

    对于一个单独实体的通常操作有3种:添加新的实体.修改实体以及删除实体. 1.添加新的实体 Entity Framework Code First添加新的实体通过调用DbSet.Add()方法来实现. ...