验证签名,腾讯官方提供的文档居然有写“密文”,如下图,切记要去掉。。。。
C# WebApi配置服务器代码分享:
public static readonly ILog BaseLogger = LogManager.GetLogger(“CheckTokenController”);
//公众平台上开发者设置的token, appID, EncodingAESKey
public static string sToken = “微信配置”;
public static string sAppID = “你的公众号ID”;
public static string sEncodingAESKey = “可随机可自定义,切记与微信配置一致”;
//用于消息去重
public static Dictionary<string, DateTime> _msgId = new Dictionary<string, DateTime>();
Tencent.WXBizMsgCrypt wxcpt = new Tencent.WXBizMsgCrypt(sToken, sEncodingAESKey, sAppID);
/// <summary>
/// 用于微信验证
/// </summary>
/// <param name="signature"></param>
/// <param name="timestamp"></param>
/// <param name="nonce"></param>
/// <param name="echoStr"></param>
/// <returns></returns>
[HttpGet]
public HttpResponseMessage Get(string signature, string timestamp, string nonce, string echoStr)
{
StreamReader sr = new StreamReader(System.Web.HttpContext.Current.Request.InputStream, Encoding.UTF8);
BaseLogger.Info(sr);
var sMsgSignature = "";
var ret = wxcpt.GenarateSinature(sToken, timestamp, nonce, ref sMsgSignature);
if (ret != 0)
{
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent("")
};
}
if (sMsgSignature == signature)
{
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(echoStr)
};
}
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent("")
};
}
/// <summary>
/// 接收微信推送的消息及事件
/// </summary>
/// <param name="signature"></param>
/// <param name="timestamp"></param>
/// <param name="nonce"></param>
/// <returns></returns>
[HttpPost]
public HttpResponseMessage Get([FromUri]string signature,[FromUri]string timestamp,[FromUri]string nonce)
{
try
{
var requestContent = Request.Content.ReadAsStringAsync().Result;
var msg = "";
var ret = wxcpt.DecryptMsg(signature, timestamp, nonce, requestContent, ref msg);
if (ret != 0)
{
BaseLogger.Error("解密失败,返回码:"+ret);
}
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(msg);
WxMessage wxMessage = new WxMessage();
wxMessage.MsgType = xmlDoc.SelectSingleNode("xml/MsgType").InnerText;//消息类型
wxMessage.FromUserName = xmlDoc.SelectSingleNode("xml/FromUserName").InnerText;//发送人
wxMessage.ToUserName = xmlDoc.SelectSingleNode("xml/ToUserName").InnerText;//接受人
wxMessage.CreateTime = xmlDoc.SelectSingleNode("xml/CreateTime").InnerText;//时间戳
string MsgId = wxMessage.MsgType == "event" ? "" : xmlDoc.SelectSingleNode("xml/MsgId").InnerText;//消息ID,事件中没有
//验证消息是否重复
if (Removal(wxMessage.MsgType, MsgId, wxMessage.FromUserName, wxMessage.CreateTime))
{
return null;
}
switch (wxMessage.MsgType)
{
case "event":
//接收关注/取消关注事件
wxMessage.EventName = xmlDoc.SelectSingleNode("xml").SelectSingleNode("Event").InnerText;
//关注回复消息
if (!string.IsNullOrEmpty(wxMessage.EventName) && wxMessage.EventName == "subscribe")
{
string content = "您好,欢迎访问****公众平台";
content = SendTextMessage(wxMessage, content);
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(content)
};
}
break;
}
if (wxMessage.MsgType == "event")
{
}
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent("")
};
}catch(Exception ex)
{
BaseLogger.Error(ex);
return new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent(ex.Message)
};
}
}
private string SendTextMessage(WxMessage wxmessage, string content)
{
string result = string.Format(Message, wxmessage.FromUserName, wxmessage.ToUserName, DateTime.Now.Ticks, content);
return result;
}
/// <summary>
/// 验证消息是否重复如果重复 返回true
/// </summary>
/// <param name=“msgTypeStr”>消息类型</param>
/// <param name=“MsgId”>消息编号</param>
/// <param name=“userName”>发送人Id</param>
/// <param name=“createTime”>时间戳</param>
/// <returns></returns>
private static bool Removal(string msgTypeStr, string MsgId, string userName, string createTime)
{
if (string.IsNullOrWhiteSpace(MsgId))
{
MsgId = userName + createTime;
}
//删除3分钟之前的消息
foreach (var item in _msgId)
{
if (item.Value < DateTime.Now.AddMinutes(-3))
{
_msgId.Remove(item.Key);
}
}
//验证消息是否存在
if (_msgId.Keys.Contains(MsgId))
{
return true;
}
else
{
_msgId[MsgId] = DateTime.Now;
}
return false;
}
public string Message
{
get
{
return @"<xml>
<ToUserName><![CDATA[{0}]]></ToUserName>
<FromUserName><![CDATA[{1}]]></FromUserName>
<CreateTime>{2}</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[{3}]]></Content>
</xml>";
}
}
真的感谢。百思不得其解。弄了两天才看到你这篇帖子才找到问题所在,一直以为是自己的代码出了问题,没想到真的是微信团队的坑
坑啊。
你这个服务端 最后部署的用的是80端口??
微信只支持80和443端口