首先,开发者在接入时,微信服务器将发送get请求到你填写的url上,此请求携带四个参数,分别signature(微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。),timestamp(时间戳),nonce(随机数),echostr(随机字符串).用 HttpContext.Current.Request.RawUrl可以获取当前请求的原始url,如下图所示:
开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。加密/校验流程如下:1. 将token、timestamp、nonce三个参数进行字典序排序
2. 将三个参数字符串拼接成一个字符串进行sha1加密
3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。下面是代码实现。首先,在你的处理程序中(我是新建了一个一般处理程序wx.ashx),判断当前请求的类型,因为接入时,是发送的GET请求,消息处理是发送的POST请求。如下图:这里我对验证url的方法进行封装。///
/// 验证url权限, 接入服务器 ///
///
///
public static bool ValidUrl(string token)
{ string echoStr = VqiRequest.GetQueryString("echoStr"); if (CheckSignature(token))
{ if (!string.IsNullOrEmpty(echoStr))
{
Utils.ResponseWrite(echoStr); return true;
}
} return false;
}///
/// 验证微信签名 ///
/// * 将token、timestamp、nonce三个参数进行字典序排序 /// * 将三个参数字符串拼接成一个字符串进行sha1加密 /// * 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。 ///
public static bool CheckSignature(string token)
{ string signature = VqiRequest.GetQueryString("signature"); string timestamp = VqiRequest.GetQueryString("timestamp"); string nonce = VqiRequest.GetQueryString("nonce"); string[] ArrTmp = { token, timestamp, nonce };
Array.Sort(ArrTmp); //字典排序
string tmpStr = string.Join("", ArrTmp);
tmpStr = Utils.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
tmpStr = tmpStr.ToLower(); if (tmpStr == signature)
{ return true;
} else
{ return false;
}
}
注:代码VqiRequest.GetQueryString是封装的QueryString请求的方法,使用的时候可以改成QueryString[“”]
处理过程如图:
将signature,timestamp,nonce三个参数放在数组中,
排序后的ArrTmp:
将三个将三个参数字符串拼接成一个字符串:
将tmpStr进行sha1加密,加密后的字符串转换成小写:
然后和签名进行对比,相同则表示验证成功。
验证成功将echoStr返回给微信。
///
/// 根据指定的密码和哈希算法生成一个适合于存储在配置文件中的哈希密码 ///
/// 要进行哈希运算的密码
/// 要使用的哈希算法
/// 经过哈希运算的密码
public static string HashPasswordForStoringInConfigFile(string str, string type)
{ return FormsAuthentication.HashPasswordForStoringInConfigFile(str, type);
} public static void ResponseWrite(string str)
{
HttpContext.Current.Response.Write(str);
HttpContext.Current.Response.End();
}