在开发者首次提交验证申请时,微信服务器将发送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");
}