1. 程式人生 > >關於微信開放平臺授權事件接收Url的配置以及引數接收

關於微信開放平臺授權事件接收Url的配置以及引數接收

關於微信開放平臺如何申請,如何配置,如何全網釋出的文章,大神們已經寫了很多,不想再造輪子,特針對微信授權事件的處理這一個點,對自己遇到的坑進行總結,也希望能給著手做微信開放平臺的小夥伴們提供一份簡單的參考資料,在寫這篇文章之前,先吐槽一下微信開放平臺的API文件,爛,真爛。

  1. 首先申請一個微信開放平臺的賬號,申請過程不贅述,很簡單的流程,但再次吐槽一次,需要交稽核費用(每年),中國大陸地區:300元,非中國大陸地區:120美元(不能理解微信的套路,難道真的有非大陸地區的國家在用微信?)
  2. 交完錢之後,等待稽核,稽核很快,大概一週時間即可
  3. 稽核通過之後,即可建立第三方平臺:建立過程如下:
     
    在開放平臺的官網,點選管理中心父選單,
     點選建立第三方平臺按鈕,即可開啟建立第三方平臺頁面
     根據自己的需要,填寫基本資訊:包括平臺名稱,選擇業務標籤,填寫平臺介紹,官方網站包括上傳Logo等
     點選下一步,選擇公眾號許可權,一點兒小提示:如果選擇了訊息通知以及自定義選單許可權之後,如果使用者公眾號授權之   後,將會導致使用者無法自定義選單以及設定訊息回覆
     最後一步,填寫開發資料,包括:授權頁發起頁域名,授權測試公眾號列表(在全網釋出稽核通過之前,該列表中的公眾   號可用於測試授權),授權事件接收Url(本文主要對該Url的填寫以及如何接收微信授權通知引數進行闡述)授權後實現   業務,主要包括:訊息校驗Token以及訊息加解密Key
    (這兩個欄位可自定義,微信授權通知後,接收的訊息用該欄位進   行  加密解密,下文會對這倆欄位如何使用進行詳細說明)訊息與事件接收URL,公眾號開發域名(第三方平臺在代公眾號   做網頁授權、呼叫JS SDK等網頁開發工作時所用的域名) 做過微信公眾號開發的小夥伴肯定很清楚,使用微信掃一掃以   及微信轉發,分享等功能的JS時,微信需要驗證是否擁有該域名許可權
  4. 關於如何配置授權事件接收Url
     
    二話不說,先貼圖


    首先域名必須為,授權頁發起頁域名中填寫的域名,我採用的C#,MVC的開發模式,在開放平臺釋出成功之後,微信會每隔10分鐘,推送授權資訊給該域名,所以在填寫時,一定要保證該方法可以被訪問
  5. 關於ReceiveController下的SysMessage方法的程式碼如下:僅供參考

    首先微信會推送6個引數給該方法,貼程式碼:
    建立物件ReceiveRequestData

     public class ReceiveRequestData
        {
            /// <summary>
            /// 微信加密簽名,signature結合了開發者填寫的token引數和請求中的timestamp引數、nonce引數。
            /// </summary>
            public string signature { get; set; }
    
    
            /// <summary>
            /// 時間戳
            /// </summary>
            public string timestamp { get; set; }
    
    
            /// <summary>
            /// 隨機數
            /// </summary>
            public string nonce { get; set; }
    
    
            /// <summary>
            /// 
            /// </summary>
            public string encrypt_type { get; set; }
    
            /// <summary>
            /// 
            /// </summary>
            public string msg_signature { get; set; }
        }
    ReceiveController中的方法接收微信推送的引數並賦值給該物件,程式碼如下:

     ReceiveRequestData postModel = new ReceiveRequestData();
     postModel.signature = HttpContext.Current.Request["signature"];
     postModel.timestamp = HttpContext.Current.Request["timestamp"];
     postModel.nonce = HttpContext.Current.Request["nonce"];
     postModel.encrypt_type = HttpContext.Current.Request["encrypt_type"];
     postModel.msg_signature = HttpContext.Current.Request["msg_signature"];
    請注意,除這些引數外,微信還會推送檔案流給該方法,接收方式如下:

    HttpContext.Current.Request.InputStream
    對接收到的引數進行解密處理
    首先宣告物件ResponseAuthEventReceiveMsg,程式碼如下
 public class ResponseAuthEventReceiveMsg
    {
        /// <summary>
        /// 第三方平臺appid
        /// </summary>
        public string AppId { get; set; }


        /// <summary>
        /// 時間戳
        /// </summary>
        public int CreateTime { get; set; }


        /// <summary>
        /// none,代表該訊息推送給服務
        /// component_verify_ticket 推送component_verify_ticket協議
        /// </summary>
        public string InfoType { get; set; }


        /// <summary>
        /// Ticket內容
        /// </summary>
        public string ComponentVerifyTicket { get; set; }


        /// <summary>
        /// 取消授權的公眾號
        /// </summary>
        public string AuthorizerAppid { get; set; }
    }

        對接收到的引數進行解密:

        ResponseAuthEventReceiveMsg response = _logic.Component_verify_ticket(postModel, HttpContext.Current.Request.InputStream);

        Component_verify_ticket方法如下:

           /// <summary>
        /// 接收component_verify_ticket協議
        /// </summary>
        /// <param name="postModel"></param>
        /// <param name="inputStream"></param>
        /// <returns></returns>
        public ResponseAuthEventReceiveMsg Component_verify_ticket(ReceiveRequestData postModel,
            Stream inputStream)
        {
            if (inputStream != null)
            {
                inputStream.Seek(0, SeekOrigin.Begin);//強制調整指標位置
                using (XmlReader xr = XmlReader.Create(inputStream))
                {
                    var postDataDocument = XDocument.Load(xr);
                    var result = Init(postDataDocument, postModel);
                    var resultMessage = new ResponseAuthEventReceiveMsg();
                    //xml to model
                    EntityHelper.FillEntityWithXml(resultMessage, result);
                    return resultMessage;
                }
            }
            return null;
        }

          Init方法如下:

 private XDocument Init(XDocument postDataDocument, ReceiveRequestData postModel)
  {
            //進行加密判斷並處理

            var postDataStr = postDataDocument.ToString();
            XDocument decryptDoc = postDataDocument;

            if (postModel != null && postDataDocument.Root.Element("Encrypt") != null && !string.IsNullOrEmpty(postDataDocument.Root.Element("Encrypt").Value))
            {
                //使用了加密
                string sToken = WeiXinConfig.ThirdPartToken;
                string sAppId = WeiXinConfig.ComponentAppId;
                string sEncodingAesKey = WeiXinConfig.ThirdPartMsgSign;
                WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAesKey, sAppId);
                string msgXml = null;
                var result = wxcpt.DecryptMsg(postModel.msg_signature, postModel.timestamp, postModel.nonce, postDataStr, ref msgXml);
                //判斷result型別
                if (result != 0)
                {
                    DevelopFileLog4Net.Instance.Info("方法:Init,驗證沒有通過");
                    //驗證沒有通過,取消執行
                    return null;
                }

                decryptDoc = XDocument.Parse(msgXml);//完成解密
            }
            return decryptDoc;
     }

          著重介紹一下Init方法中的sToken引數、sEncodingAesKey引數、sAppId引數

           sAppId引數:開放平臺釋出成功之後,微信會為使用者分配一個AppId,此處即為該引數
           sToken引數:在申請開放平臺時,填寫開發資料時,填寫的訊息校驗Token
           sEncodingAesKey引數:在申請開放平臺時,填寫開發資料時,填寫的訊息加解密Key

           至於WXBizMsgCrypt物件中的DecryptMsg方法,廢話不說,貼圖:
          

                      根據開發語言下載加解密物件即可。