zoukankan      html  css  js  c++  java
  • 微信小程序【消息推送服务器认证C# WebAPI】

    参考微信开发文档:

    https://developers.weixin.qq.com/miniprogram/dev/api/custommsg/callback_help.html

    代码可用

    /// <summary>
    /// 接口认证
    /// </summary>
    /// <param name="echostr"></param>
    /// <param name="signature"></param>
    /// <param name="timestamp"></param>
    /// <param name="nonce"></param>
    /// <returns></returns>
    [HttpGet]
    public async Task<HttpResponseMessage> wx(string echostr, string signature, string timestamp, string nonce)
    {
        string token = "token";
        if (!CheckSignature(token, signature, timestamp, nonce))
            echostr = "验证不正确";
        HttpResponseMessage responseMessage = new HttpResponseMessage { Content = new StringContent(echostr, Encoding.GetEncoding("UTF-8"), "text/plain") };
     
        return responseMessage;
    }
    /// <summary>
    /// 接收客服消息
    /// </summary>
    /// <returns></returns>
    [HttpPost]
    public async Task<HttpResponseMessage> wx()
    {
        LogHelper log = new LogHelper();
        var content = await Request.Content.ReadAsStringAsync();
        log.LogError(content);
        HttpResponseMessage responseMessage = new HttpResponseMessage();
        return responseMessage;
    }
    /// <summary>
    /// 验证微信签名
    /// </summary>
    private bool CheckSignature(string token, string signature, string timestamp, string nonce)
    {
        string[] ArrTmp = { token, timestamp, nonce };
     
        Array.Sort(ArrTmp);
        string tmpStr = string.Join("", ArrTmp);
        var data = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(tmpStr));
        var sb = new StringBuilder();
        foreach (var t in data)
        {
            sb.Append(t.ToString("X2"));
        }
        tmpStr = sb.ToString();
        tmpStr = tmpStr.ToLower();
     
        if (tmpStr == signature)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

     推荐代码:使用 Senparc.Weixin SDK

    该版本是用一般处理程序做的,当初在微信配置中填的是此地址,没有修改成WebApi。大家可以参考做成WebApi的

    引用:

    using Senparc.Weixin;
    using Senparc.Weixin.MP;
    using Senparc.Weixin.MP.Entities.Request;
    public class wxapi : IHttpHandler
        {
            //public static readonly string Token = Config.SenparcWeixinSetting.Token;//与微信公众账号后台的Token设置保持一致,区分大小写。
            //public static readonly string EncodingAESKey = Config.SenparcWeixinSetting.EncodingAESKey;//与微信公众账号后台的EncodingAESKey设置保持一致,区分大小写。
            //public static readonly string AppId = Config.SenparcWeixinSetting.WeixinAppId;//与微信公众账号后台的AppId设置保持一致,区分大小写。
            public static string Token = CachedConfigContext.Current.SettingConfig.token;
            public static string EncodingAESKey = CachedConfigContext.Current.SettingConfig.EncodingAESKey;
            public static string AppId = CachedConfigContext.Current.SettingConfig.appId;
    
            readonly Func<string> _getRandomFileName = () => DateTime.Now.ToString("yyyyMMdd-HHmmss") + Guid.NewGuid().ToString("n").Substring(0, 6);
    
            public void ProcessRequest(HttpContext context)
            {
                string postString = string.Empty;
    
                PostModel postModel = new PostModel();
                postModel.Signature = HttpContext.Current.Request.QueryString["signature"];
                postModel.Timestamp = HttpContext.Current.Request.QueryString["timestamp"];
                postModel.Nonce = HttpContext.Current.Request.QueryString["nonce"];
                postModel.Msg_Signature = HttpContext.Current.Request.QueryString["msg_signature"];
                var openid = HttpContext.Current.Request.QueryString["openid"];
                var encrypt_type = HttpContext.Current.Request.QueryString["encrypt_type"];
    
                if (HttpContext.Current.Request.HttpMethod.ToUpper() == "POST")
                {
                    //using (Stream stream = HttpContext.Current.Request.InputStream)
                    //{
                    //    Byte[] postBytes = new Byte[stream.Length];
                    //    stream.Read(postBytes, 0, (Int32)stream.Length);
                    //    postString = Encoding.UTF8.GetString(postBytes);
                    //}
    
                    //if (!string.IsNullOrEmpty(postString))
                    //{
                    //    //Execute(postString);
                    //}
                    if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token))
                    {
                        HttpContext.Current.Response.Write("error");
                        HttpContext.Current.Response.End();
                    }
                    #region 打包 PostModel 信息
    
                    postModel.Token = Token;//根据自己后台的设置保持一致
                    postModel.EncodingAESKey = EncodingAESKey;//根据自己后台的设置保持一致
                    postModel.AppId = AppId;//根据自己后台的设置保持一致
    
                    #endregion
    
                    //v4.2.2之后的版本,可以设置每个人上下文消息储存的最大数量,防止内存占用过多,如果该参数小于等于0,则不限制
                    var maxRecordCount = 10;
    
                    //自定义MessageHandler,对微信请求的详细判断操作都在这里面。
                    var messageHandler = new CustomMessageHandler(HttpContext.Current.Request.InputStream, postModel, maxRecordCount);
    
                    #region 设置消息去重
    
                    /* 如果需要添加消息去重功能,只需打开OmitRepeatedMessage功能,SDK会自动处理。
                     * 收到重复消息通常是因为微信服务器没有及时收到响应,会持续发送2-5条不等的相同内容的RequestMessage*/
                    messageHandler.OmitRepeatedMessage = true;//默认已经开启,此处仅作为演示,也可以设置为false在本次请求中停用此功能
    
                    #endregion
    
                    try
                    {
    
                        #region 记录 Request 日志
    
                        var logPath = HttpContext.Current.Server.MapPath(string.Format("~/logs/MP/{0}/", DateTime.Now.ToString("yyyy-MM-dd")));
                        if (!Directory.Exists(logPath))
                        {
                            Directory.CreateDirectory(logPath);
                        }
    
                        //测试时可开启此记录,帮助跟踪数据,使用前请确保logs文件夹存在,且有读写权限。
                        messageHandler.RequestDocument.Save(Path.Combine(logPath, string.Format("{0}_Request_{1}_{2}.txt", _getRandomFileName(),
                            messageHandler.RequestMessage.FromUserName,
                            messageHandler.RequestMessage.MsgType)));
                        if (messageHandler.UsingEcryptMessage)
                        {
                            messageHandler.EcryptRequestDocument.Save(Path.Combine(logPath, string.Format("{0}_Request_Ecrypt_{1}_{2}.txt", _getRandomFileName(),
                                messageHandler.RequestMessage.FromUserName,
                                messageHandler.RequestMessage.MsgType)));
                        }
    
                        #endregion
    
                        //执行微信处理过程
                        messageHandler.Execute();
    
                        #region 记录 Response 日志
    
                        //测试时可开启,帮助跟踪数据
    
                        //if (messageHandler.ResponseDocument == null)
                        //{
                        //    throw new Exception(messageHandler.RequestDocument.ToString());
                        //}
                        if (messageHandler.ResponseDocument != null)
                        {
                            messageHandler.ResponseDocument.Save(Path.Combine(logPath, string.Format("{0}_Response_{1}_{2}.txt", _getRandomFileName(),
                                messageHandler.ResponseMessage.ToUserName,
                                messageHandler.ResponseMessage.MsgType)));
                        }
    
                        if (messageHandler.UsingEcryptMessage && messageHandler.FinalResponseDocument != null)
                        {
                            //记录加密后的响应信息
                            messageHandler.FinalResponseDocument.Save(Path.Combine(logPath, string.Format("{0}_Response_Final_{1}_{2}.txt", _getRandomFileName(),
                                messageHandler.ResponseMessage.ToUserName,
                                messageHandler.ResponseMessage.MsgType)));
                        }
    
                        #endregion
    
                        //return Content(messageHandler.ResponseDocument.ToString());//v0.7-
                        //return new WeixinResult(messageHandler);//v0.8+
                        var res = new Senparc.Weixin.MP.MvcExtension.FixWeixinBugWeixinResult(messageHandler);//为了解决官方微信5.0软件换行bug暂时添加的方法,平时用下面一个方法即可
                        HttpContext.Current.Response.Write(res.Content);
                        HttpContext.Current.Response.End();
                    }
                    catch (Exception ex)
                    {
                        #region 异常处理
                        WeixinTrace.Log("MessageHandler错误:{0}", ex.Message);
    
                        using (TextWriter tw = new StreamWriter(HttpContext.Current.Server.MapPath("~/logs/Error_" + _getRandomFileName() + ".txt")))
                        {
                            tw.WriteLine("ExecptionMessage:" + ex.Message);
                            tw.WriteLine(ex.Source);
                            tw.WriteLine(ex.StackTrace);
                            //tw.WriteLine("InnerExecptionMessage:" + ex.InnerException.Message);
    
                            if (messageHandler.ResponseDocument != null)
                            {
                                tw.WriteLine(messageHandler.ResponseDocument.ToString());
                            }
    
                            if (ex.InnerException != null)
                            {
                                tw.WriteLine("========= InnerException =========");
                                tw.WriteLine(ex.InnerException.Message);
                                tw.WriteLine(ex.InnerException.Source);
                                tw.WriteLine(ex.InnerException.StackTrace);
                            }
    
                            tw.Flush();
                            tw.Close();
                        }
                        HttpContext.Current.Response.Write("");
                        HttpContext.Current.Response.End();
                        #endregion
                    }
    
                }
                else
                {
                    if (CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token))
                    {
                        string echostr = HttpContext.Current.Request.QueryString["echoStr"];
                        //返回随机字符串则表示验证通过
                        HttpContext.Current.Response.Write(echostr);
                        HttpContext.Current.Response.End();
                    }
                }
            }
    
            public bool IsReusable
            {
                get
                {
                    return false;
                }
            }
        }
  • 相关阅读:
    ubuntu在图形界面下打开一个终端
    [置顶] 屠夫与大夫
    service bound(一)
    Android Interface Definition Language (AIDL)
    service bound(二)
    移动应用开发原则
    Service bound(三)
    Linux 安装SSH服务
    JDK中设计模式
    Bad Hair Day【单调栈】
  • 原文地址:https://www.cnblogs.com/kennyliu/p/9553037.html
Copyright © 2011-2022 走看看