最近在公司接到了一个开发微信公众号的项目,于是自己通过几天的探索终于搞定了。今天首先给大家分享一个个人服务器和微信公众号之间的通信功能。

其实和微信之间的通信就是一种签名的认证。

在url里面填写的是你的服务器用来接收微信消息的地址。在提交的时候微信会发起GET请求,同时携带如图参数

 在后台我们用一个控制器去接收具体代码实现如下:

 1 readonly WeChatOutService weChat = new WeChatOutService();
 2         /// <summary>
 3         /// 微信通信接收/发射器
 4         /// </summary>
 5         /// <returns>响应内容</returns>
 6         public ActionResult WeChatResult()
 7         {
 8             if (HttpContext.Request.HttpMethod.ToUpper() == "GET")
 9             {
10                 // 微信加密签名    
11                 string signature = Request.QueryString["signature"];
12                 // 时间戳    
13                 string timestamp = Request.QueryString["timestamp"];
14                 // 随机数    
15                 string nonce = Request.QueryString["nonce"];
16                 // 随机字符串    
17                 string echostr = Request.QueryString["echostr"];
18                 if (weChat.CheckSignature(signature, timestamp, nonce))
19                 {
20                     return Content(echostr);
21                 }
22             }
23             if (HttpContext.Request.HttpMethod.ToUpper() == "POST")
24             {
25                 StreamReader stream = new StreamReader(Request.InputStream);
26                 string xml = stream.ReadToEnd();
27                 string result = weChat.ProcessRequest(xml);
28                 return Content(result, "text/xml");
29             }
30             return Content("");
31         }

通过获取的参数进行加密验证

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Security.Cryptography;
 4 using System.Text;
 5 using System.Web;
 6 using System.Xml;
 7 using Newtonsoft.Json;
 8 
 9 namespace Service.WeChat
10 {
11     public abstract class WeChatOutService
12     {
13         public string AppId { get; set; }
14         public string AppSecret { get; set; }
15         public string Token { get; set; }
16 
17         /// <summary>
18         /// 微信通信验证
19         /// </summary>
20         /// <param name="signature">signature</param>
21         /// <param name="timestamp">timestamp</param>
22         /// <param name="nonce">nonce</param>
23         /// <returns>验证是否通过</returns>
24         public bool CheckSignature(string signature, string timestamp, string nonce)
25         {
26             string[] arr = new string[] { Token, timestamp, nonce };
27             // 将token、timestamp、nonce三个参数进行字典序排序    
28             Array.Sort<String>(arr);
29 
30             StringBuilder content = new StringBuilder();
31             foreach (string item in arr)
32             {
33                 content.Append(item);
34             }
35 
36             string tmpStr = ShaEncrypt(content.ToString());
37             LogHelper.WriteLog("后台加密字符串:" + tmpStr, "signature:" + signature + "timestamp:" + timestamp + "nonce:" + nonce);
38 
39             // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信    
40             return tmpStr != null && tmpStr.Equals(signature);
41         }
42 
43         /// <summary>
44         /// 加密
45         /// </summary>
46         /// <param name="sourceString">加密字符串</param>
47         /// <returns>加密之后字符串</returns>
48         private static string ShaEncrypt(string sourceString)
49         {
50             byte[] strRes = Encoding.Default.GetBytes(sourceString);
51             HashAlgorithm iSha = new SHA1CryptoServiceProvider();
52             strRes = iSha.ComputeHash(strRes);
53             StringBuilder enText = new StringBuilder();
54             foreach (byte iByte in strRes)
55             {
56                 enText.AppendFormat("{0:x2}", iByte);
57             }
58             return enText.ToString();
59         }       
60 }

注意:URL配置必须要使用80端口的访问地址,不能使用IP地址;作为屌丝的我自己买了服务器和域名做测试的