ホームページ  >  記事  >  WeChat アプレット  >  WeChat ポータルとアプリケーションの C# 開発 - WeChat エンタープライズ アカウントからのメッセージとイベントの受信、処理、復号化

WeChat ポータルとアプリケーションの C# 開発 - WeChat エンタープライズ アカウントからのメッセージとイベントの受信、処理、復号化

高洛峰
高洛峰オリジナル
2017-02-18 09:42:181994ブラウズ

前回のエッセイ「WeChat ポータルとアプリケーションの C# 開発 (19) - WeChat エンタープライズ アカウントのメッセージ送信 (テキスト、画像、ファイル、音声、ビデオ、グラフィック メッセージなど)」では、エンタープライズ アカウントのメッセージ送信について紹介しました。公式の特別な声明メッセージは暗号化せずに送信されます。ただし、Web サイトのサーバーであるコールバック サーバーでは、WeChat から送信されるメッセージは暗号化されており、メッセージとイベントを復号化するためにクラス ライブラリを呼び出す必要があります。公式のサンプルが不完全であるため、多くの時間を費やしました。最後に、受信したさまざまなメッセージとイベントが正常に復号化されました。この記事では主に、WeChat エンタープライズ アカウントでのメッセージとイベントの受信、処理、復号化の操作を紹介します。

1. エンタープライズ アカウントのコールバック モードの設定

パブリック アカウントと同様に、WeChat エンタープライズ アカウントで二次開発が必要な場合は、次のインターフェイスに示すように、対応するコールバック パラメーターをバックグラウンドで設定する必要があります。

C#开发微信门户及应用-微信企业号的消息和事件的接收处理及解密

これらを設定してチェックに合格すると、独自の WeChat アプリケーション サーバーでメッセージを送受信できるようになります。

コールバックメッセージのエントリでは、POSTデータと通常のGETデータを別々に処理する必要があります。GETデータはWeChat独自の検証処理であり、POSTデータはWeChatメッセージの対話的な操作です。

    /// <summary>
    /// 企业号回调信息接口。统一接收并处理信息的入口。    /// </summary>
    public class corpapi : IHttpHandler
    {        /// <summary>
        /// 处理企业号的信息        /// </summary>
        /// <param name="context"></param>
        public void ProcessRequest(HttpContext context)
        {

上記では、メッセージを処理するための一般的なアプリケーション ハンドラーを定義しました。

次に、さまざまなメッセージ タイプ (POST、GET メソッド) を分離し、それに応じて処理します。

                    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, accountInfo);
                        }
                    }                    else
                    {
                        Auth(accountInfo);
                    }

2. WeChatコールバックメッセージの検証

以下は、WeChatのコールバックモードと検証URLの手順です。

URL の有効性を確認します

上記の情報を送信すると、企業アカウントは入力された URL に GET リクエストを送信します。GET リクエストには 4 つのパラメーターが含まれます。 企業は取得時に URL デコード処理を行う必要があります。そうでない場合、検証は失敗します。

パラメータ説明必須ですか?msg_signatureWeChat暗号化署名、msg_signatureは、企業によって入力されたトークン、リクエスト内のタイムスタンプ、nonceパラメータ、および暗号化されたメッセージを組み合わせます。 bodyはいtimestamptimestampはnonce乱数はechostr暗号化されたランダムですmsg_encrypt 形式で提供される文字列。 echostr 平文を復号して返す必要があります。random、msg_len、msg、$CorpID は最初の検証に含める必要があります。

企业通过参数msg_signature对请求进行校验,如果确认此次GET请求来自企业号,那么企业应用对echostr参数解密并原样返回echostr明文(不能加引号),则接入验证生效,回调模式才能开启。

后续回调企业时都会在请求URL中带上以上参数(echostr除外),校验方式与首次验证URL一致。

根据上面的说明,我们需要获取这些参数,然后调用微信提供的消息处理函数进行加解密处理。

在验证URL的Auth(accountInfo);操作里面,我们可以看到核心的内容如下所示,就是获取到这些传递过来的参数信息,然后交给基类处理消息的签名内容。

                        #region 具体处理逻辑                        string echoString = HttpContext.Current.Request.QueryString["echoStr"];                        string signature = HttpContext.Current.Request.QueryString["msg_signature"];//企业号的 msg_signature
                        string timestamp = HttpContext.Current.Request.QueryString["timestamp"];                        string nonce = HttpContext.Current.Request.QueryString["nonce"];                        string decryptEchoString = "";                        if (new CorpBasicApi().CheckSignature(token, signature, timestamp, nonce, corpId, encodingAESKey, echoString, ref decryptEchoString))
                        {                            if (!string.IsNullOrEmpty(decryptEchoString))
                            {
                                HttpContext.Current.Response.Write(decryptEchoString);
                                HttpContext.Current.Response.End();
                            }
                        } 
                        #endregion

验证代码部门如下所示。

        /// <summary>
        /// 验证企业号签名        /// </summary>
        /// <param name="token">企业号配置的Token</param>
        /// <param name="signature">签名内容</param>
        /// <param name="timestamp">时间戳</param>
        /// <param name="nonce">nonce参数</param>
        /// <param name="corpId">企业号ID标识</param>
        /// <param name="encodingAESKey">加密键</param>
        /// <param name="echostr">内容字符串</param>
        /// <param name="retEchostr">返回的字符串</param>
        /// <returns></returns>
        public bool CheckSignature(string token, string signature, string timestamp, string nonce, string corpId, string encodingAESKey, string echostr, ref string retEchostr)
        {
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(token, encodingAESKey, corpId);            int result = wxcpt.VerifyURL(signature, timestamp, nonce, echostr, ref retEchostr);            if (result != 0)
            {
                LogTextHelper.Error("ERR: VerifyURL fail, ret: " + result);                return false;
            }            return true;
        }

3、企业号的消息处理

 上面介绍了,微信企业号对URL的验证过程,还有另外一个消息处理过程,就是微信服务器把消息发送给我们自己的应用服务器进行处理的过程,我们应用服务器需要在收到消息后,及时进行常规回复处理。

也就是下面的代码逻辑。

                    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, accountInfo);
                        }
                    }

同样,我们给微信服务器回应消息的时候,我们也需要获得相应的参数,然后再行构造信息回答。

            string echoString = HttpContext.Current.Request.QueryString["echoStr"];            string signature = HttpContext.Current.Request.QueryString["msg_signature"];//企业号的 msg_signature
            string timestamp = HttpContext.Current.Request.QueryString["timestamp"];            string nonce = HttpContext.Current.Request.QueryString["nonce"];

而另外一些参数信息,则是来源于我们企业号账号的配置参数。

            //获取配置参数并对加解密函数初始化
            string CorpToken = accountInfo.Token;            string AESKey = accountInfo.EncodingAESKey;            string CorpId = accountInfo.CorpID;

然后使用微信提供的消息加解密类,就可以顺利对消息进行加解密的处理了。具体操作代码如下所示。

            //根据参数信息,初始化微信对应的消息加密解密类
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(CorpToken, AESKey, CorpId);            //对收到的密文进行解析处理
            string sMsg = "";  // 解析之后的明文
            int flag = wxcpt.DecryptMsg(signature, timestamp, nonce, postStr, ref sMsg);            if (flag == 0)
            {                //LogTextHelper.Info("记录解密后的数据:");                //LogTextHelper.Info(sMsg);//记录解密后的数据
                CorpApiDispatch dispatch = new CorpApiDispatch();                string responseContent = dispatch.Execute(sMsg);                //加密后并发送                //LogTextHelper.Info(responseContent);
                string encryptResponse = "";
                timestamp = DateTime.Now.DateTimeToInt().ToString();
                wxcpt.EncryptMsg(responseContent, timestamp, nonce, ref encryptResponse, ref signature);

                HttpContext.Current.Response.ContentEncoding = Encoding.UTF8;
                HttpContext.Current.Response.Write(encryptResponse);
            }            else
            {
                LogTextHelper.Info("解密消息失败!");
            }

最终,我们把解密完成的消息交给对应的封装类进行统一处理就可以了。

                CorpApiDispatch dispatch = new CorpApiDispatch();                string responseContent = dispatch.Execute(sMsg);

这样我们在企业号API的封装,就可以只需要关注消息如何应答的逻辑就可以了,其他的不用关心。

C#开发微信门户及应用-微信企业号的消息和事件的接收处理及解密  

 

更多C#开发微信门户及应用-微信企业号的消息和事件的接收处理及解密 相关文章请关注PHP中文网!

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。