微信公众号开发C#系列-2、微信公众平台接入指南
概述
微信公众平台消息接口的工作原理大概可以这样理解:从用户端到公众号端一个流程是这样的,用户发送消息到微信服务器,微信服务器将接收到的消息post到用户接入时填写的url中,在url处理程序中,首先判断消息的合法性,判断成功后根据消息体的内容做相应的处理。原理很容易理解,接触过socket的可能理解起来更容易。对于微信开发者模式的接入官网文档非常的简洁,对于初学者很多都摸不着头脑,微信官方技术文档的接入指南可以参考接入指南
大致步骤就是:
- 填写服务器配置
- 验证服务器地址的有效性
- 依据接口文档实现业务逻辑
准备工作
要接入微信,首先我们需要一个微信公众号,相信做微信公众号开发的朋友都会遇到这样的问题,就是微信公众号提供的接口权限问题。如果是个人订阅号,官方提供的接口很少,很多接口都不能用。如果想测试接口功能怎么办?其实,微信公众号官方给我们提供一个微信公众测试号,测试号除了不能用微信支付接口,其他接口基本都可以用获取并且可以使用。下面我就教大家如何申请微信公众号测试号。全微信扫一扫公众平台测试账号系统登录即可,非常的方便。微信公众平台测试账号系统地址:公众平台测试账号系统登录后我们就可以轻松愉快的进行下面的玩耍了。对于常规的微信公众号接入方式与测试公众号大同小异,这儿成功了其他的类似。
填写服务器配置与验证消息的确来自微信服务器
- 填写服务器配置
在填写服务器配置之前我们需要了解一下微信与我们的服务器交互的过程:
当我们在微信app上,给公众号发送一条消息时,这条消息实际上是发送到了微信的服务器上,此时微信的服务器就会对消息进行封装成某种格式的数据比如xml格式,再转发到我们配置好的URL上,所以该URL实际就是我们处理数据的一个请求路径。因此该URL必须是能暴露给外界访问的一个公网地址,不能使用内网地址,生产环境可以申请腾讯云,阿里云服务器等,但在开发环境中可暂时利用一些软件来完成内网穿透以便于修改和测试,如NATAPP,花生壳等软件,使用起来也很方便,在本地安装对应的软件,配置运行后,直接使用软件分配的临时域名来访问本地应用即可,只是偶尔会存在网络不稳定的情况,具体的外网映射工具与调试的方法后面的文章我们会接受。
有了这样一个基本的概念后,我们看下接口配置信息相关的说明。
接口配置如下图所示:
对于测试号信息中的appid与appsecret两个属性是唯一的标识,每个测试号都会有自己的appid与appsecret ,是比较重要的信息,不要随意发给别人。
- appid:是公众号开发识别码,配合开发者密码可调用公众号的接口能力。
- appsecret:是校验公众号开发者身份的密码,具有极高的安全性。
服务器地址URL是开发者用来接收微信消息和事件的接口URL,是我们服务器的响应微信请求的地址。
假设我们自己的服务器域名是www.rdiframework.net,准备用/WeiXin/WeChat/来接收消息,就填写:
http://www.rdiframework.net/WeiXin/WeChat/
Token可以任意填写,为了安全性和防止黑客攻击建议设置得复杂一些,并要防止泄露。
测试号一般只需要填写URL与Token两项内容,真实项目的填写还要填写EncodingAESKey,可以由开发者手动填写或随机生成,将用作消息体加解密密钥。
开发者还可选择消息加解密方式:明文模式、兼容模式和安全模式,具体可参看开发者文档。
另请注意,微信公众号接口地址必须以http://或https://开头,分别支持80端口和443端口。
- 验证消息的确来自微信服务器
当我们填入url与token的值,并提交后,微信会发送一个get请求到我们填写的url上,并且携带4个参数,而signature参数结合了开发者填写的token参数和请求中的timestamp参数、nonce参数来做的加密签名,我们在后台需要对该签名进行校验,看是否合法。实际上,我们发现微信带过来的4个参数中并没有带token参数,仅有signature是和token有关的,所以我们应该在本地应用中也准备一个和填入的token相同的参数,再通过微信传入的timestamp与nonce做相同算法的加密操作,若结果与微信传入的signature相同,即为合法,则原样返回echostr参数,代表接入成功,否则不做处理,则接入失败。
详细流程可参考微信官方提供的逻辑流程图,我们的应用需要以该流程图的步骤来实现。
下面为我们以.NET MVC代码实现get请求样例代码,可供参考:
[HttpGet]
[ActionName("Index")]
public Task<ActionResult> Get(string signature, string timestamp, string nonce, string echostr)
{
return Task.Factory.StartNew(() =>
{
if (CheckSignature.Check(signature, timestamp, nonce, "WeiXinToken"))
{
return echostr; //返回随机字符串则表示验证通过
}
else
{
return "failed:" + signature + "," + CheckSignature.GetSignature(timestamp, nonce, weixinOfficialAccountEntity.Token) + "。" + "如果你在浏览器中看到这句话,说明此地址可以被作为微信公众账号后台的Url,请注意保持Token一致。";
}
}).ContinueWith<ActionResult>(task => Content(task.Result));
}
上面的代码注意token不是微信服务器发过来的,而是我们自己写死的一个常量,就是在微信后台填写的Token,这儿我填写的是:WeiXinToken
依据接口文档实现业务逻辑
验证URL有效性成功后我们就可以接收来自微信的数据,并对接收到的数据按需做相应的业务处理。用户每次向公众号发送消息、或者产生自定义菜单、或产生微信支付订单等情况时,开发者填写的服务器配置URL将得到微信服务器推送过来的消息和事件,开发者可以依据自身业务逻辑进行响应,如回复消息。
公众号调用各接口时,一般会获得正确的结果,具体结果可见对应接口的说明。返回错误时,可根据返回码来查询错误原因。全局返回码说明
微信后台发送消息是一个POST请求,但和普通的POST请求不同的是,首先,URL会带上signature、timestamp、nonce这3个参数:
POST http://www.rdiframework.net/WeiXin/WeChat/?signature=xxx×tamp=123456&nonce=123
然后,HTTP请求的BODY是一个不规范的XML:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1348831860</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[this is a test]]></Content>
<MsgId>1234567890123456</MsgId>
</xml>
我们自己的服务器只需要处理该XML,然后,向微信返回一个类似如下的XML:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
</xml>
就可以完成消息的回复。微信后台要求必须在5秒内回复,最多重试3次,否则我们自己的回复消息就到达不了用户的手机了。如果我们自己的服务器无法在5秒内回复,就回复一个空字符串,告诉微信服务器,不用重试了,这个消息处理不了,不给用户回复了。
上面的交互逻辑看起来很简单,但实际上坑有很多。
首先,微信服务器发送的POST请求根本就不符合HTTP规范。原则上POST请求不应该在URL上附带参数,但微信后台偏偏要这么干,这就让很多编程语言的标准框架无法获取到POST参数,因为标准的POST参数是从HTTP BODY中解析的。所以从POST获取URL参数就需要用到更底层的代码。现在无论做什么都讲究的是效率,什么东西有现成的我们就不需要去重复的造轮子,直接拿来使用即可。在.net下微信开发我们推荐使用开源的SENPARC.WEIXIN SDK,这个sdk基本完成了微信全系列的操作功能,使用的客户多,一直在升级中,可放心使用。简单的几行代码就可以实现一个功能,何乐而不为呢。
接收微信的请求代码参考:
[HttpPost]
[ActionName("Index")]
public Task<ActionResult> Post(PostModel postModel)
{
return Task.Factory.StartNew<ActionResult>(() =>
{
if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, "WeiXinToken"))
{
return new WeixinResult("参数错误!");
}
postModel.Token = "****Token***";
postModel.EncodingAESKey = "***EncodingAESKey***"; //根据自己后台的设置保持一致
postModel.AppId = "****AppId***"; //根据自己后台的设置保持一致
//自定义MessageHandler,对微信请求的详细判断操作都在这里面。
var messageHandler = new CustomMessageHandler(Request.InputStream, postModel,10);
messageHandler.Execute(); //执行微信处理过程
return new FixWeixinBugWeixinResult(messageHandler);
}).ContinueWith<ActionResult>(task => task.Result);
}
吐槽:微信和微信公众平台虽然产品很先进,但后台API设计得确实不咋地。由于API是给开发人员使用的,所以,设计一个好的API要从开发人员的角度出发。与其使用笨重的XML,不如使用更符合Web潮流的JSON。
例如验证服务器:
{
"signature": "xxx",
"timestamp": 123456,
"nonce": "xxx",
"action": "verify",
"data": {
"echostr": "echo"
}
}
这样设计的API,各种编程语言都能处理,而且处理逻辑更简单,速度更快。
参考文章
RDIFramework.NET — 基于.NET的快速信息化系统开发框架 — 系列目录
RDIFramework.NET ━ .NET快速信息化系统开发框架 ━ 工作流程组件介绍
RDIFramework.NET框架SOA解决方案(集Windows服务、WinForm形式与IIS形式发布)-分布式应用
RDIFramework.NET代码生成器全新V3.5版本发布-重大升级
一路走来数个年头,感谢RDIFramework.NET框架的支持者与使用者,大家可以通过下面的地址了解详情。
RDIFramework.NET官方网站:http://www.rdiframework.net/
RDIFramework.NET官方博客:http://blog.rdiframework.net/
同时需要说明的,以后的所有技术文章以官方网站为准,欢迎大家收藏!
RDIFramework.NET框架由专业团队长期打造、一直在更新、一直在升级,请放心使用!
欢迎关注RDIFramework.net框架官方公众微信(微信号:guosisoft),及时了解最新动态。
扫描二维码立即关注
微信公众号开发C#系列-2、微信公众平台接入指南的更多相关文章
- 微信公众号开发C#系列-11、生成带参数二维码应用场景
1.概述 我们在微信公众号开发C#系列-7.消息管理-接收事件推送章节有对扫描带参数二维码事件的处理做了讲解.本篇主要讲解通过微信公众号开发平台提供的接口生成带参数的二维码及应用场景. 微信公众号平台 ...
- 微信公众号开发C#系列-7、消息管理-接收事件推送
1.概述 在微信用户和公众号产生交互的过程中,用户的某些操作会使得微信服务器通过事件推送的形式通知到开发者在开发者中心处设置的服务器地址,从而开发者可以获取到该信息.其中,某些事件推送在发生后,是允许 ...
- 微信公众号开发C#系列-1、微信公众平台注册
微信公众号简介 微信公众号分为服务号.订阅号.企业号,订阅号可以个人申请,服务号和企业号要有企业资质才可以. 我们所说的微信公众号开发主要指的是公众号的账号类型,公众号的账号类型分为订阅号.服务号.企 ...
- 微信公众号开发C#系列-12、微信前端开发利器:WeUI
1.前言 通过前面系列文章的学习与讲解,相信大家已经对微信的开发有了一个全新的认识.后端基本能够基于盛派的第三方sdk搞定大部分事宜,剩下的就是前端了.关于手机端的浏览器的兼容性问题相信一直是开发者们 ...
- 微信公众号开发C#系列-9、多公众号集中管理
1.概述 通过前面8篇关于微信开发相关文章的学习,我们已经对微信常用开发有了一个比较深入的了解.前面的文章都是基于某一特定公众号的,在现实业务中同一单位个体运营着不至一个公众号,此时就需要对多个公众号 ...
- 微信公众号开发C#系列-5、用户和用户组管理-支持同步
1.概述 眼前时下流行的经济有个叫粉丝经济,粉丝带动收益.一个好运营良好的公众号肯定会有一大批的粉丝团,如何挖掘粉丝来产生效益,是微信营销的关键.微信公众号后台本身提供了粉丝(用户)与用户分组的管理, ...
- 微信公众号开发C#系列-4、获取接口调用凭证
概述 获取接口调用凭证实质就是获取access_token.在微信接口开发中,许多服务的使用都离不开Access Token,Access Token相当于打开这些服务的钥匙,正常情况下会在7200秒 ...
- .NET微信公众号开发-1.0初始微信公众号
一.前言 微信公众号是开发者或商家在微信公众平台上申请的应用账号,该帐号与QQ账号互通,通过公众号,商家可在微信平台上实现和特定群体的文字.图片.语音.视频的全方位沟通.互动 .形成了一 种主流的线上 ...
- 微信公众号开发《三》微信JS-SDK之地理位置的获取,集成百度地图实现在线地图搜索
本次讲解微信开发第三篇:获取用户地址位置信息,是非常常用的功能,特别是服务行业公众号,尤为需要该功能,本次讲解的就是如何调用微信JS-SDK接口,获取用户位置信息,并结合百度地铁,实现在线地图搜索,与 ...
随机推荐
- POJ_2653_Pick-up sticks_判断线段相交
POJ_2653_Pick-up sticks_判断线段相交 Description Stan has n sticks of various length. He throws them one a ...
- Asp.Net 中Grid详解两种方法使用LigerUI加载数据库数据填充数据分页
1.关于LigerUI: LigerUI 是基于jQuery 的UI框架,其核心设计目标是快速开发.使用简单.功能强大.轻量级.易扩展.简单而又强大,致力于快速打造Web前端界面解决方案,可以应用于. ...
- iOS 支付(含支付宝、银联、微信)
资料 支付宝 //文档idk都包含了安卓.iOS版 银 联 银联官网资料 Demo Demo给了一个订单号,做测试使用,若出现支付失败什么的,可能是已经被别人给支付了,或者是服务器订单过期了 ~ 一. ...
- Heartbeat实现集群高可用热备
公司最近需要针对服务器实现热可用热备,这几天也一直在琢磨这个方面的东西,今天做了一些Heartbeat方面的工作,在此记录下来,给需要的人以参考. Heartbeat 项目是 Linux-HA 工程的 ...
- 关于Python元祖,列表,字典,集合的比较
定义 方法 列表 可以包含不同类型的对象,可以增减元素,可以跟其他的列表结合或者把一个列表拆分,用[]来定义的 eg:aList=[123,'abc',4.56,['inner','list'], ...
- Guess 任意猜
age_of_oldboy = 56 count = 0 while count <3: guess_age = int(input("guess age:")) if gu ...
- 第十四章——循环神经网络(Recurrent Neural Networks)(第一部分)
由于本章过长,分为两个部分,这是第一部分. 这几年提到RNN,一般指Recurrent Neural Networks,至于翻译成循环神经网络还是递归神经网络都可以.wiki上面把Recurrent ...
- java IO流全面总结
流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作. Ja ...
- MediatR 知多少
引言 首先不用查字典了,词典查无此词.猜测是作者笔误将Mediator写成MediatR了.废话少说,转入正题. 先来简单了解下这个开源项目MediatR(作者Jimmy Bogard,也是开源项目A ...
- <转载>Android性能优化之HashMap,ArrayMap和SparseArray
本篇博客来自于转载,打开原文地址已经失效,在此就不贴出原文地址了,如原作者看到请私信我可用地址,保护原创,人人有责. Android开发者都知道Lint在我们使用HashMap的时候会给出警告—— ...