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

参数描述
signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
timestamp 时间戳
nonce 随机数
echostr 随机字符串

 

 

 

 

开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。

加密/校验流程如下:
1. 将token、timestamp、nonce三个参数进行字典序排序
2. 将三个参数字符串拼接成一个字符串进行sha1加密
3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

 

签名:

        public static bool checkSignature(String signature, string token, String timestamp, String nonce, out string errMsg)
        {
            try
            {
                String[] arr = new String[] { token, timestamp, nonce };
                // 将token、timestamp、nonce三个参数进行字典序排序  
                Array.Sort(arr);
                StringBuilder content = new StringBuilder();
                for (int i = 0; i < arr.Length; i++)
                {
                    content.Append(arr[i]);
                }
                var sha1Encryoted = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(content.ToString(), "SHA1");
                if (signature.ToUpper().Equals(sha1Encryoted.ToUpper()))
                {
                    errMsg = string.Empty;
                    return true;
                }
                else
                {
                    errMsg = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\n\r\t" + "签名比对失败。本地sha1为:" + sha1Encryoted;
                    return false;
                }
            }
            catch (Exception e)
            {
                errMsg = e.Message;
                return false;
            }
        }

 

使用:

public ActionResult Index(int id)
{

 var reqList = this.Request.QueryString;

var signature = reqList["signature"];
            var timestamp = reqList["timestamp"];
            var nonce = reqList["nonce"];
            var echostr = reqList["echostr"];

            var testString = string.Format("signature:{0}, timestamp:{1}, nonce:{2}, echostr:{3}",
                                            signature,
                                            timestamp,
                                            nonce,
                                            echostr);

            var wxAccount = WXAccountRepository.DetailByShopID(id);
            if (null == wxAccount)
            {
                WXLogRepository.WriteLog("微信管理", "验证微信帐号", id, "微信帐号不存在");
                MakeSun.WeiXinData.Repository.ShopRepository.UpdateStatus(false, id);
                return new EmptyResult();
            }

            var errMsg = string.Empty;
            bool checkResult = WeiXinConfig.checkSignature(signature, wxAccount.ToKen, timestamp, nonce, out errMsg);
            if (checkResult)
            {
                WXLogRepository.WriteLog("微信管理", "验证微信帐号", id, "验证微信帐号成功");
                MakeSun.WeiXinData.Repository.ShopRepository.UpdateStatus(true, id);
                return Content(echostr);
            }

            WXLogRepository.WriteLog("微信管理", "验证微信帐号", id, "验证微信帐号失败。");
            MakeSun.WeiXinData.Repository.ShopRepository.UpdateStatus(false, id);
            return Content("fail");
  }

 

 

 

posted on 2014-03-12 11:54  日月草方  阅读(845)  评论(0编辑  收藏  举报