码迷,mamicode.com
首页 > 其他好文 > 详细

黑皮接招

时间:2017-12-09 13:04:37      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:对比   url   通用   auth   tor   请求   rdf   mode   length   

  1 public class API : IHttpHandler, IRequiresSessionState
  2     {
  3 
  4         public void ProcessRequest(HttpContext context)
  5         {
  6             context.Response.ContentType = "text/plain";
  7             if (context.Request.HttpMethod.ToLower() == "post")
  8             {
  9                 //回复消息的时候也需要验证消息,这个很多开发者没有注意这个,存在安全隐患  
 10                 //微信中 谁都可以获取信息 所以 关系不大 对于普通用户 但是对于某些涉及到验证信息的开发非常有必要
 11                 if (CheckSignature())
 12                 {
 13                     //接收消息
 14                     ReceiveXml();
 15                 }
 16                 else
 17                 {
 18                     HttpContext.Current.Response.Write("消息并非来自微信");
 19                     HttpContext.Current.Response.End();
 20                 }
 21             }
 22             else
 23             {
 24                 CheckWechat();
 25             }
 26         }
 27 
 28         #region 验证微信签名
 29         /// <summary>
 30         /// 返回随机数表示验证成功
 31         /// </summary>
 32         private void CheckWechat()
 33         {
 34             if (string.IsNullOrEmpty(HttpContext.Current.Request.QueryString["echoStr"]))
 35             {
 36                 HttpContext.Current.Response.Write("消息并非来自微信");
 37                 HttpContext.Current.Response.End();
 38             }
 39             string echoStr = HttpContext.Current.Request.QueryString["echoStr"];
 40             if (CheckSignature())
 41             {
 42                 HttpContext.Current.Response.Write(echoStr);
 43                 HttpContext.Current.Response.End();
 44             }
 45         }
 46 
 47         /// <summary>
 48         /// 验证微信签名
 49         /// </summary>
 50         /// <returns></returns>
 51         /// * 将token、timestamp、nonce三个参数进行字典序排序
 52         /// * 将三个参数字符串拼接成一个字符串进行sha1加密
 53         /// * 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。
 54         private bool CheckSignature()
 55         {
 56             string access_token = "sohovan";
 57 
 58             string signature = HttpContext.Current.Request.QueryString["signature"].ToString();
 59             string timestamp = HttpContext.Current.Request.QueryString["timestamp"].ToString();
 60             string nonce = HttpContext.Current.Request.QueryString["nonce"].ToString();
 61             string[] ArrTmp = { access_token, timestamp, nonce };
 62             Array.Sort(ArrTmp);     //字典排序
 63             string tmpStr = string.Join("", ArrTmp);
 64             tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
 65 
 66             if (tmpStr.ToLower() == signature)
 67             {
 68                 return true;
 69             }
 70             else
 71             {
 72                 return false;
 73             }
 74         }
 75         #endregion
 76 
 77         #region 接收消息
 78         /// <summary>
 79         /// 接收微信发送的XML消息并且解析
 80         /// </summary>
 81         private void ReceiveXml()
 82         {
 83             Stream requestStream = System.Web.HttpContext.Current.Request.InputStream;
 84             byte[] requestByte = new byte[requestStream.Length];
 85             requestStream.Read(requestByte, 0, (int)requestStream.Length);
 86             string requestStr = Encoding.UTF8.GetString(requestByte);
 87 
 88             if (!string.IsNullOrEmpty(requestStr))
 89             {
 90                 //封装请求类
 91                 XmlDocument requestDocXml = new XmlDocument();
 92                 requestDocXml.LoadXml(requestStr);
 93                 XmlElement rootElement = requestDocXml.DocumentElement;
 94                 WxXmlModel WxXmlModel = new WxXmlModel();
 95                 WxXmlModel.ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText;
 96                 WxXmlModel.FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText;
 97                 WxXmlModel.CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText;
 98                 WxXmlModel.MsgType = rootElement.SelectSingleNode("MsgType").InnerText;
 99 
100                 switch (WxXmlModel.MsgType)
101                 {
102                     case "text"://文本
103                         WxXmlModel.Content = rootElement.SelectSingleNode("Content").InnerText;
104                         break;
105                     case "image"://图片
106                         WxXmlModel.PicUrl = rootElement.SelectSingleNode("PicUrl").InnerText;
107                         break;
108                     case "event"://事件
109                         WxXmlModel.Event = rootElement.SelectSingleNode("Event").InnerText;
110                         if (WxXmlModel.Event != "TEMPLATESENDJOBFINISH")//关注类型
111                         {
112                             WxXmlModel.EventKey = rootElement.SelectSingleNode("EventKey").InnerText;
113                         }
114                         break;
115                     default:
116                         break;
117                 }
118            
119                 ResponseXML(WxXmlModel);//回复消息
120             }
121         }
122         #endregion
123 
124         #region 回复消息
125         private void ResponseXML(WxXmlModel WxXmlModel)
126         {
127             QrCodeApi QrCodeApi = new wxapi.QrCodeApi();
128             string XML = "";
129             switch (WxXmlModel.MsgType)
130             { 
131                 case "text"://文本回复
132                     XML = sohovan.com.wxapi.ResponseMessage.GetText(WxXmlModel.FromUserName, WxXmlModel.ToUserName, WxXmlModel.Content);
133                     break;
134                 case "event":
135                     switch (WxXmlModel.Event)
136                     {
137                         case "subscribe":
138                             if (string.IsNullOrEmpty(WxXmlModel.EventKey))
139                             {
140                                 XML = sohovan.com.wxapi.ResponseMessage.GetText(WxXmlModel.FromUserName, WxXmlModel.ToUserName,"关注成功");
141                             }
142                             else
143                             {
144                                 XML = sohovan.com.wxapi.ResponseMessage.SubScanQrcode(WxXmlModel.FromUserName, WxXmlModel.ToUserName, WxXmlModel.EventKey);//扫描带参数二维码先关注后推送事件
145                             }
146                             break;
147                         case "SCAN":
148                             XML = sohovan.com.wxapi.ResponseMessage.ScanQrcode(WxXmlModel.FromUserName, WxXmlModel.ToUserName, WxXmlModel.EventKey);//扫描带参数二维码已关注 直接推送事件
149                             break;
150                     }
151                     break;
152                 default://默认回复
153                     break;
154             }
155             HttpContext.Current.Response.Write(XML);
156             HttpContext.Current.Response.End();
157         }
158         #endregion
159 
160         public bool IsReusable
161         {
162             get
163             {
164                 return false;
165             }
166         }
167     }

 

黑皮接招

标签:对比   url   通用   auth   tor   请求   rdf   mode   length   

原文地址:http://www.cnblogs.com/kejie/p/8011045.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!