亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

首頁 微信小程式 微信開發(fā) 微信公眾平臺開發(fā):AccessToken自動管理機制

微信公眾平臺開發(fā):AccessToken自動管理機制

Feb 27, 2017 pm 01:40 PM
微信大眾平臺

在《微信大眾平臺開發(fā):通用介面說明》中,我介紹了取得AccessToken(通用介面)的方法。

在實際的開發(fā)過程中,所有的高階介面都需要提供AccessToken,因此我們每次在呼叫高階介面之前,都需要執(zhí)行一次取得AccessToken的方法,例如:

var accessToken = AccessTokenContainer.TryGetAccessToken(appId, appSecret);

或者當你對appId和appSecret進行過全域註冊之後,也可以這樣做:

var accessToken = AccessTokenContainer.GetAccessToken(_appId);

然後使用這個accessToken輸入到高級介面的方法中,例如我們可以這樣取得選單:

var result = CommonApi.GetMenu(accessToken);

  通常情況下,這已經(jīng)是一個很簡潔的API呼叫過程。但是我們不願意就這樣停止,我們準備把幾乎所有的API呼叫都縮短到一行。

? ? ?這麼做的同時,除了讓程式碼更簡便,我們還有兩個願望:

讓API可以自動處理已經(jīng)變更的AccessToken(在負載平衡等多個伺服器同時操作同在一個微信公眾號的情況下,可能出現(xiàn)AccessToken在外部被刷新,導致本機AccessToken失效的情況),並且重新取得、傳回最終正確的API結(jié)果。

不改變目前API呼叫的方式,完全向下相容。

?

呼叫程式碼

修改之後,我們可以直接這樣一行呼叫API,每次只需要提供一個appId:

var result = CommonApi.GetMenu(appId);

目前在執(zhí)行之前,我們需要像以前一樣全域註冊appId和appSecret:

AccessTokenContainer.Register(_appId, _appSecret);//全局只需注冊一次,例如可以放在Global的Application_Start()方法中。

可以看到,原先的accessToken換成了appId(新版本仍然支援輸入accessToken),省去了獲取accessToken的過程。具體的過程請見下文說明。

SDK原始碼實作過程

? ? ?之前為了實現(xiàn)自動處理(預料外的)過期的AccessToken,SDK已經(jīng)提供了Senparc.Weixin.MP/AccessTokenHandlerWapper.Do()方法。這次升級將AccessTokenHandlerWapper.cs重新命名為ApiHandlerWapper.cs,廢除Do()方法,新增TryCommonApi()方法,程式碼如下:

namespace Senparc.Weixin.MP
{
    /// <summary>
    /// 針對AccessToken無效或過期的自動處理類
    /// </summary>
    public static class ApiHandlerWapper
    {
        /// <summary>
        /// 使用AccessToken進行操作時,如果遇到AccessToken錯誤的情況,重新獲取AccessToken一次,并重試。
        /// 使用此方法之前必須使用AccessTokenContainer.Register(_appId, _appSecret);或JsApiTicketContainer.Register(_appId, _appSecret);方法對賬號信息進行過注冊,否則會出錯。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="fun"></param>
        /// <param name="accessTokenOrAppId">AccessToken或AppId。如果為null,則自動取已經(jīng)注冊的第一個appId/appSecret來信息獲取AccessToken。</param>
        /// <param name="retryIfFaild">請保留默認值true,不用輸入。</param>
        /// <returns></returns>
        public static T TryCommonApi<T>(Func<string, T> fun, string accessTokenOrAppId = null, bool retryIfFaild = true) where T : WxJsonResult
        {
            string appId = null;
            string accessToken = null;
 
            if (accessTokenOrAppId == null)
            {
                appId = AccessTokenContainer.GetFirstOrDefaultAppId();
                if (appId == null)
                {
                    throw new WeixinException("尚無已經(jīng)注冊的AppId,請先使用AccessTokenContainer.Register完成注冊(全局執(zhí)行一次即可)!");
                }
            }
            else if (ApiUtility.IsAppId(accessTokenOrAppId))
            {
                if (!AccessTokenContainer.CheckRegistered(accessTokenOrAppId))
                {
                    throw new WeixinException("此appId尚未注冊,請先使用AccessTokenContainer.Register完成注冊(全局執(zhí)行一次即可)!");
                }
 
                appId = accessTokenOrAppId;
            }
            else
            {
                //accessToken
                accessToken = accessTokenOrAppId;
            }
 
 
            T result = null;
 
            try
            {
                if (accessToken == null)
                {
                    var accessTokenResult = AccessTokenContainer.GetAccessTokenResult(appId, false);
                    accessToken = accessTokenResult.access_token;
                }
                result = fun(accessToken);
            }
            catch (ErrorJsonResultException ex)
            {
                if (!retryIfFaild
                    && appId != null
                    && ex.JsonResult.errcode == ReturnCode.獲取access_token時AppSecret錯誤或者access_token無效)
                {
                    //嘗試重新驗證
                    var accessTokenResult = AccessTokenContainer.GetAccessTokenResult(appId, true);
                    accessToken = accessTokenResult.access_token;
                    result = TryCommonApi(fun, appId, false);
                }
            }
            return result;
        }
    }
}

對應API的原始程式碼原來是這樣的:

/// <summary>
/// 獲取當前菜單,如果菜單不存在,將返回null
/// </summary>
/// <param name="accessToken"></param>
/// <returns></returns>
public static GetMenuResult GetMenu(string accessToken)
{
    var url = string.Format("https://api.weixin.qq.com/cgi-bin/menu/get?access_token={0}", accessToken);
 
    var jsonString = HttpUtility.RequestUtility.HttpGet(url, Encoding.UTF8);
    //var finalResult = GetMenuFromJson(jsonString);
 
    GetMenuResult finalResult;
    JavaScriptSerializer js = new JavaScriptSerializer();
    try
    {
        var jsonResult = js.Deserialize<GetMenuResultFull>(jsonString);
        if (jsonResult.menu == null || jsonResult.menu.button.Count == 0)
        {
            throw new WeixinException(jsonResult.errmsg);
        }
 
        finalResult = GetMenuFromJsonResult(jsonResult);
    }
    catch (WeixinException ex)
    {
        finalResult = null;
    }
 
    return finalResult;
}

現(xiàn)在使用TryCommonApi()方法之後:

/// <summary>
/// 獲取當前菜單,如果菜單不存在,將返回null
/// </summary>
/// <param name="accessTokenOrAppId">AccessToken或AppId。當為AppId時,如果AccessToken錯誤將自動獲取一次。當為null時,獲取當前注冊的第一個AppId。</param>
/// <returns></returns>
public static GetMenuResult GetMenu(string accessTokenOrAppId)
{
    return ApiHandlerWapper.TryCommonApi(accessToken =>
      {
          var url = string.Format("https://api.weixin.qq.com/cgi-bin/menu/get?access_token={0}", accessToken);
 
          var jsonString = HttpUtility.RequestUtility.HttpGet(url, Encoding.UTF8);
          //var finalResult = GetMenuFromJson(jsonString);
 
          GetMenuResult finalResult;
          JavaScriptSerializer js = new JavaScriptSerializer();
          try
          {
              var jsonResult = js.Deserialize<GetMenuResultFull>(jsonString);
              if (jsonResult.menu == null || jsonResult.menu.button.Count == 0)
              {
                  throw new WeixinException(jsonResult.errmsg);
              }
 
              finalResult = GetMenuFromJsonResult(jsonResult);
          }
          catch (WeixinException ex)
          {
              finalResult = null;
          }
 
          return finalResult;
      }, accessTokenOrAppId);
}

我們可以觀察到有這樣幾個變化:

? ? 1. 原先的accessToken變數(shù)名稱改為accessTokenOrAppId(新版本中所有相關(guān)接口都將如此變化)。

? ? 修改之後,這個參數(shù)可以輸入accessToken(向下相容),也可以輸入appId(無需再取得accessToken),SDK會根據(jù)字串長度自動判斷屬於哪種類型的參數(shù)。提供的參數(shù)有3種可能:

? ? ? ? a)?appId。使用appId需要事先對appId和appSecret進行全域註冊(上文已說過),當呼叫API的過程中發(fā)現(xiàn)快取的AccessToken過期時,SDK會自動刷新AccessToken,並重新嘗試一次API請求,確保傳回正確的結(jié)果。如果appId沒有被註冊過,會拋出例外。

? ? ? ? b)?accessToken。這種情況將使用原始的請求方式,如果accessToken無效,將直接拋出異常,不會重試。

? ? ? ? c)?null。當accessTokenOrAppId參數(shù)為null時,SDK會自動取得全域註冊的第一個appId。如果某個應用程式只針對一個確定的微訊號開發(fā),可以使用這種方法。當全域沒有註冊任何appId時,將會拋出例外。

? ? 2. 原方法內(nèi)的存取API的程式碼沒有做任何修改,只是被嵌套到了return ApiHandlerWapper.TryCommonApi(accessToken =>{...},accessTokenOrAppId)的方法中,以委託的形式出現(xiàn),目的是為了在第一次可能的請求失敗之後,SDK可以自動執(zhí)行一次一模一樣的程式碼。

?

? ? 此功能已在Senparc.Weixin.MP v12.1中發(fā)布。


更多微信公眾平臺開發(fā):AccessToken自動管理機制相關(guān)文章請關(guān)注PHP中文網(wǎng)!


本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權(quán)歸原作者所有。本站不承擔相應的法律責任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72