此文将分两篇讲解,主要分为以下几步

  1. 签名校验;
  2. 首次提交验证申请;
  3. 接收消息;
  4. 被动响应消息(返回XML);
  5. 映射图灵消息及微信消息;

其实图灵机器人搭载微信公众号很简单,只需要把图灵的地址配到公众后台就可以了。

不过这样做之后也就没有任何扩展的可能了,因此自己实现一套!

一、签名校验

在开发者首次提交验证申请时,微信服务器将发送GET请求到填写的URL上,并且带上四个参数(signature、timestamp、nonce、echostr),开发者通过对签名(即signature)的效验,来判断此条消息的真实性。

此后,每次开发者接收用户消息的时候,微信也都会带上前面三个参数(signature、timestamp、nonce)访问开发者设置的URL,开发者依然通过对签名的效验判断此条消息的真实性。效验方式与首次提交验证申请一致。

根据微信开发者平台中的描述,我们在首次提交验证申请及接收用户消息时,都需要校验签名以确保消息来源真实。

参与签名的参数为timestampnoncetoken(即开发者中心中配置的Token令牌)

加密/校验流程如下:

  1. 将token、timestamp、nonce三个参数进行字典序排序(此处注意:是三个参数的值,而不是按参数名排序)
  2. 将三个参数字符串拼接成一个字符串进行sha1加密
  3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

由于这个东西在接收消息时是通用的,我们可以使用授权过滤器AuthorizeAttribute来实现。

using System.Configuration;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.Linq;
using System.Web.Http.Controllers; using Efh.Core.Security; namespace Efh.Blog.Web.Areas.WeiXin.Filter
{
public class WXAuthorizeAttribute : AuthorizeAttribute
{
/// <summary>
/// 签名Key
/// </summary>
private string _wxToken = ConfigurationManager.AppSettings["WXToken"]; /// <summary>
/// 是否通过授权
/// </summary>
/// <param name="actionContext">上下文</param>
/// <returns>是否成功</returns>
protected override bool IsAuthorized(HttpActionContext actionContext)
{
var requestQueryPairs = actionContext.Request.GetQueryNameValuePairs().ToDictionary(k => k.Key, v => v.Value);
if (requestQueryPairs.Count == 0
|| !requestQueryPairs.ContainsKey("timestamp")
|| !requestQueryPairs.ContainsKey("signature")
|| !requestQueryPairs.ContainsKey("nonce"))
{
return false;
} string[] waitEncryptParamsArray = new[] { _wxToken, requestQueryPairs["timestamp"], requestQueryPairs["nonce"] }; string waitEncryptParamStr = string.Join("", waitEncryptParamsArray.OrderBy(m => m)); string encryptStr = HashAlgorithm.SHA1(waitEncryptParamStr); return encryptStr.ToLower().Equals(requestQueryPairs["signature"].ToLower());
} /// <summary>
/// 处理未授权请求
/// </summary>
/// <param name="actionContext">上下文</param>
protected sealed override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
actionContext.Response = actionContext.Request.CreateResponse(
HttpStatusCode.Unauthorized, new { status = "sign_error" });
}
}
}

将该特性声明在我们的微信Controller或者Action上,我们的签名校验便完成了。

二、首次提交验证申请

首次提交验证申请,微信服务器来调的时候是Get请求,而且要求我们将echostr原样返回。

注意,是原样返回。不是XML,也不是Json,<string>echostr</string>和"echostr"都是不行的!

囊中羞涩,本人使用的是虚拟主机搭载在原有的项目中,故新建微信区域(WeiXin)来实现。WeiXinAreaRegistration.cs文件如下:

public class WeiXinAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "WeiXin";
}
} public override void RegisterArea(AreaRegistrationContext context)
{
context.Routes.MapHttpRoute(
"WeiXinProcessor",
"WeiXin/{controller}",
new { controller = "Processor" }
);
}
}

新建Processor控制器,实现如下:

[WXAuthorize]
public class ProcessorController : ApiController
{
public HttpResponseMessage Get()
{
var requestQueryPairs = Request.GetQueryNameValuePairs().ToDictionary(k => k.Key, v => v.Value); return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(requestQueryPairs["echostr"]),
};
}
}

上述我们便实现了首次微信的验证。

三、接收消息

微信将请求的消息分为六种:文本消息、图片消息、语音消息、视频消息、地理位置消息、链接消息,其实我们还可以将事件推送也理解为其中一种。

将响应的消息分为六种:

1. 回复文本消息

2. 回复图片消息

3. 回复语音消息

4. 回复视频消息

5. 回复音乐消息

6. 回复图文消息

。我们在这儿主要使用文本消息和图文消息。

分析后我们发现,ToUserNameFromUserNameCreateTimeMsgType是所有消息共有的参数。同时也是我们响应时必需的参数。

我们创建消息基类和消息类型枚举如下

public class BaseMsg
{
public string ToUserName { get; set; } public string FromUserName { get; set; } public long CreateTime { get; set; } public MsgType MsgType { get; set; }
} public enum MsgType
{
[XmlEnum("event")]
Event,
[XmlEnum("text")]
Text,
[XmlEnum("image")]
Image,
[XmlEnum("voice")]
Voice,
[XmlEnum("video")]
Video,
[XmlEnum("music")]
Music,
[XmlEnum("news")]
News
}

此处枚举字段标注的XmlEnum稍候解释。

而后按照各消息类型的非共有的参数,分别创建对应消息的实体类

文本消息:

[XmlRoot("xml")]
public class TextMsg : BaseMsg
{
public string Content { get; set; }
}

图文消息:

[XmlRoot("xml")]
public class NewsMsg : BaseMsg
{
public int ArticleCount { get; set; } [XmlArray("Articles")]
[XmlArrayItem("item")]
public List<NewsInfo> Articles { get; set; }
} public class NewsInfo
{
public string Title { get; set; } public string Description { get; set; } public string PicUrl { get; set; } public string Url { get; set; }
}

等等。

刚才下班,朋友喊了,勿勿忙忙就提交了。。。现在继续!

接下来我们就可以开始接收微信的消息了

微信是通过Post,从正文中以XML的格式将参数传递过来的

var requestContent = Request.Content.ReadAsStreamAsync().Result;

将正文参数读取出来后,转为Xml

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(requestContent);

这样,我们便可以读取到我们需要的内容了

string msgTypeStr = xmlDoc.SelectSingleNode("xml/MsgType").InnerText;//消息类型
string userName = xmlDoc.SelectSingleNode("xml/FromUserName").InnerText;//来源用户标识
string efhName = xmlDoc.SelectSingleNode("xml/ToUserName").InnerText;//我们的用户标识

而后,我们根据消息类型,进行进一步的处理。

静候片刻,第二篇马上奉上...

使用web api开发微信公众号,调用图灵机器人接口(一)的更多相关文章

  1. 使用web api开发微信公众号,调用图灵机器人接口(二)

    此文将分两篇讲解,主要分为以下几步 签名校验; 首次提交验证申请; 接收消息; 被动响应消息(返回XML); 映射图灵消息及微信消息; 此篇为第二篇. 被动响应消息(返回XML) 上一篇中,我们已经可 ...

  2. 小机器人自动回复(python,可扩展开发微信公众号的小机器人)

    api来之图灵机器人.我们都知道微信公众号可以有自动回复,我们先用python脚本编写一个简单的自动回复的脚本,利用图灵机器人的api. http://www.tuling123.com/help/h ...

  3. Asp.Net Web API开发微信后台

    如果说用Asp.Net开发微信后台是非主流,那么Asp.Net Web API的微信后台绝对是不走寻常路. 需要说明的是,本人认为Asp.Net Web API在开发很多不同的请求方法的Restful ...

  4. 使用vue开发微信公众号下SPA站点的填坑之旅

    原文发表于本人博客,点击进入使用vue开发微信公众号下SPA站点的填坑之旅 本文为我创业过程中,开发项目的填坑之旅.作为一个技术宅男,我的项目是做一个微信公众号,前后端全部自己搞定,不浪费国家一分钱^ ...

  5. PHP开发微信公众号(一)二维码的获取

    要开发微信公众号,首先进行需要注册一个,然后认证.这就不用多说了. 当然如果没有,也可以去申请一个测试号来使用,地址:https://mp.weixin.qq.com/debug/cgi-bin/sa ...

  6. Java开发微信公众号(五)---微信开发中如何获取access_token以及缓存access_token

    获取access_token是微信api最重要的一个部分,因为调用其他api很多都需要用到access_token.比如自定义菜单接口.客服接口.获取用户信息接口.用户分组接口.群发接口等在请求的时候 ...

  7. vue开发微信公众号--开发准备

    由于工作项目的原因,需要使用vue开发微信公众号,但是这种微信公众号更多是将APP套了一个微信的壳子,除了前面的授权和微信有关系以外,其他的都和微信没多大的关系了,特此记录 开发流程 首先需要在电脑上 ...

  8. spring-boot-route(二十三)开发微信公众号

    在讲微信公众号开发之前,先来大概了解一下微信公众号.微信公众号大体上可以分为服务号和订阅号,订阅号和服务号的区别如下: 服务号可以申请微信支付功能. 服务号只能由企业申请,订阅号可以有企业或个人申请. ...

  9. Java开发微信公众号(四)---微信服务器post消息体的接收及消息的处理

    在前几节文章中我们讲述了微信公众号环境的搭建.如何接入微信公众平台.以及微信服务器请求消息,响应消息,事件消息以及工具处理类的封装:接下来我们重点说一下-微信服务器post消息体的接收及消息的处理,这 ...

随机推荐

  1. 详细透彻解读Git与SVN的区别(集中式VS分布式)

    Git是目前世界上最先进的分布式版本控制系统,其实 Git 跟 SVN一样有自己的集中式版本库或服务器,但是Git 更倾向于被使用于分布式模式,也就是每个开发人员从中心版本库/服务器上chect ou ...

  2. buff/cache 内容释放

    oscache远程服务器特别卡,top命令查看获得 buff/cache 占据内存特别大,使用以下命令清理缓存: swap清理: swapoff -a && swapon -a 注意: ...

  3. Sailing

    Sailing 目录 1基本信息 2歌曲简介 3歌词内容 4歌手简介 5专辑介绍 1基本信息编辑 歌曲: Sailing 所属专辑: Atlantic Crossing 艺人:Rod Stewart[ ...

  4. ZT C语言链表操作(新增单向链表的逆序建立)

    这个不好懂,不如看 转贴:C语言链表基本操作http://www.cnblogs.com/jeanschen/p/3542668.html ZT 链表逆序http://www.cnblogs.com/ ...

  5. Java使用HTTP编程模拟多参数多文件表单信息的请求与处理

    本文目的是提供Java环境下模拟浏览器页面提交多参数多文件表单请求以及解析请求的Demo代码.这里用Java提供的HttpURLConnection类做HTTP请求,再原始点可以直接使用socket. ...

  6. python里的splitlines具体解释

        Python的split方法函数能够切割字符串成列表,默认是以空格作为分隔符sep来切割字符串. In [1]: s = "www jeapedu com" In [2]: ...

  7. 利用mpvue开发微信小程序

    最近公司部门负责人提出需求需要开发一款微信小程序,由于本人之前是做前端开发的,对于小程序开发一窍不通,但是很多时候我们都是把不会做变成我会学.于是便在网上寻找小程序开发教程,相比于相生的小程序开发,本 ...

  8. 基于PHP的cURL快速入门教程 (小偷采集程序)

    cURL 是一个利用URL语法规定来传输文件和数据的工具,支持很多协议,如HTTP.FTP.TELNET等.很多小偷程序都是使用这个函数.     最爽的是,PHP也支持 cURL 库.本文将介绍 c ...

  9. http协议cookie结构分析

    Http协议中Cookie详细介绍   Cookie总是保存在客户端中,按在客户端中的存储位置,可分为内存Cookie和硬盘Cookie.内存Cookie由浏览器维护,保存在内存中,浏览器关闭后就消失 ...

  10. ZOJ 3992 One-Dimensional Maze(思维题)

    L - One-Dimensional Maze Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & % ...