看过微信公众号开发文档的都知道这文档有多坑,我就不点名微信支付了,官方提供的DEMO都跑不起来,有几处坑,要改对才行。
吐槽完毕,开整。
意思就是你填一个地址,验证通过后,以后微信各种事件都会推送到你的服务器中。开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,注意是GET请求。
参数如下面图表所示。
参数 | 描述 |
signature | 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 |
timestamp | 时间戳 |
nonce | 随机数 |
echostr | 随机字符串 |
注意了注意了,既然以后所有的推送加验证都是在这个地址进行,那怎么区分是推送还是验证呢。往下继续看,你会发现接下来的微信提交数据来你的服务器都是POST一个xml数据,而验证是get。所以我们只需要分开get和post就好了。
/// <param name="signature">微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。</param>
/// <param name="timestamp">时间戳</param>
/// <param name="nonce">随机数</param>
/// <param name="echostr">随机字符串</param>
public void Valid(string signature, string timestamp, string nonce, string echostr)
{
//GET URL需要正确响应微信发送的Token验证
if (System.Web.HttpContext.Current.Request.RequestType == "GET")
{
WeChaRequestModel model = new WeChaRequestModel()
{
signature = signature,
timestamp = timestamp,
nonce = nonce,
echostr = echostr
};
if (CheckSignature(model))
{
if (!string.IsNullOrEmpty(model.signature))
{
//将随机生成的 echostr 参数 原样输出
Response.Write(model.echostr);
//截止输出流
Response.End();
}
}
}
else
{ //服务器接收微信传过来的数据,自己写
}
}
/// <summary>
/// 验证签名,检验是否是从微信服务器上发出的请求
/// </summary>
/// <param name="model">请求参数模型 Model</param>
/// <returns>是否验证通过</returns>
private bool CheckSignature(WeChaRequestModel model)
{
string signature, timestamp, nonce, tempStr;
//获取请求来的参数
signature = model.signature;
Write("signature:" + signature);
timestamp = model.timestamp;
Write("timestamp:" + timestamp);
nonce = model.nonce;
Write("nonce:" + nonce);
//创建数组,将 Token, timestamp, nonce 三个参数加入数组
string[] array = { Token, timestamp, nonce };
//进行排序
Array.Sort(array);
//拼接为一个字符串
tempStr = String.Join("", array);
//对字符串进行 SHA1加密
tempStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tempStr, "SHA1").ToLower();
Write("计算的密钥为:" + tempStr);
//判断signature 是否正确
if (tempStr.Equals(signature))
{
return true;
}
else
{
return false;
}
}
忘记贴WeChaRequestModel里的字段了,不想手敲的可以直接来拷贝。
/// <summary>
/// 接入微信服务字段,以下均为微信提供的文档字段一模一样
/// </summary>
public class WeChaRequestModel
{
/// <summary>
/// 微信加密签名
/// </summary>
public string signature { get; set; }
/// <summary>
/// 时间戳
/// </summary>
public string timestamp { get; set; }
/// <summary>
/// 随机数
/// </summary>
public string nonce { get; set; }
/// <summary>
/// 随机字符串
/// </summary>
public string echostr { get; set; }
}
总结:
大概流程就是这样,微信会以get的方式传四个字段过来,将token、timestamp、nonce三个参数进行字典序排序,然后将三个参数字符串拼接成一个字符串进行sha1加密最后再返回微信传过来的随机数,微信收到你返回的正确值,就代表验证通过。