ホームページ  >  記事  >  WeChat アプレット  >  WeChatパブリックプラットフォーム開発:AccessToken自動管理機構

WeChatパブリックプラットフォーム開発:AccessToken自動管理機構

高洛峰
高洛峰オリジナル
2017-02-27 13:40:543027ブラウズ

「WeChatパブリックプラットフォーム開発:一般インターフェースの説明」では、AccessToken(一般インターフェース)の取得方法を紹介しました。

実際の開発プロセスでは、すべての高レベルインターフェイスが AccessToken を提供する必要があるため、高レベルインターフェイスを呼び出すたびに、次のような AccessToken を取得するメソッドを実行する必要があります:

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

または appId を実行するときグローバル登録後、次のこともできます:

var accessToken = AccessTokenContainer.GetAccessToken(_appId);

次に、この accessToken を使用して高度なインターフェイスのメソッドに入ります。 たとえば、次のようなメニューを取得できます:

var result = CommonApi.GetMenu(accessToken);

通常、これはすでに非常に単純です。 API呼び出し処理。しかし、そこで終わりではなく、ほぼすべての API 呼び出しを 1 行に短縮するつもりです。

これを行う際、コードを簡素化することに加えて、次の 2 つの願いもあります:

変更された AccessToken を API が自動的に処理できるようにする (ロード バランシングなどの複数のサーバーが同じ WeChat 公式アカウントを同時に動作させる場合、 AccessToken が外部で更新され、ローカルの AccessToken が無効になる場合があります)、最終的な正しい API 結果を再度取得して返す必要があります。

現在の API 呼び出しメソッドは変更せず、完全な下位互換性があります。

呼び出しコード

変更後は、この行で API を直接呼び出すことができ、毎回 appId を指定するだけで済みます:

var result = CommonApi.GetMenu(appId);

現在、実行前に、以前と同様に appId と appSecret をグローバルに登録する必要があります。

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

ご覧のとおり、元の accessToken は appId に置き換えられ (新しいバージョンでも accessToken の入力をサポートしています)、accessToken を取得するプロセスが不要になっています。具体的な処理については以下で説明します。

SDKソースコード実装プロセス

以前は、(予期せずに)期限切れのAccessTokenを自動的に処理するために、SDKはSenparc.Weixin.MP/AccessTokenHandlerWapper.Do()メソッドを提供していました。このアップグレードにより、AccessTokenHandlerWapper.cs の名前が ApiHandlerWapper.cs に変更され、Do() メソッドが廃止され、TryCommonApi() メソッドが追加されました。 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,则自动取已经注册的第一个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("尚无已经注册的AppId,请先使用AccessTokenContainer.Register完成注册(全局执行一次即可)!");
                }
            }
            else if (ApiUtility.IsAppId(accessTokenOrAppId))
            {
                if (!AccessTokenContainer.CheckRegistered(accessTokenOrAppId))
                {
                    throw new WeixinException("此appId尚未注册,请先使用AccessTokenContainer.Register完成注册(全局执行一次即可)!");
                }
 
                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;
        }
    }
}

次の変更を確認できます:

1. 元の accessToken 変数名が accessTokenOrAppId に変更されます (新しいバージョンのすべての関連インターフェイスはこのように変更されます)。

変更後、このパラメーターは、accessToken (下位互換性) または appId (accessToken を取得する必要はありません) を使用して入力できます。SDK は、文字列の長さに基づいて、どのタイプのパラメーターに属するかを自動的に決定します。指定できるパラメーターは 3 つあります:

a) appId。 appId を使用するには、事前に appId と appSecret をグローバルに登録する必要があります (前述のとおり)。API 呼び出し中にキャッシュされた AccessToken の有効期限が切れていることが判明した場合、SDK は AccessToken を自動的に更新し、正しい結果が得られることを確認するために API リクエストを再試行します。戻ってきた。 。 appId が登録されていない場合は、例外がスローされます。

b) アクセストークン。この場合、accessToken が無効な場合は、再試行せずに、元のリクエスト メソッドが使用されます。

c) null。 accessTokenOrAppId パラメーターが null の場合、SDK はグローバルに登録された最初の appId を自動的に取得します。アプリケーションが特定の WeChat ID に対してのみ開発されている場合は、この方法を使用できます。 appId がグローバルに登録されていない場合、例外がスローされます。

2. 元のメソッドで API にアクセスするためのコードはまったく変更されておらず、メソッド return ApiHandlerWapper.TryCommonApi(accessToken =>{...},accessTokenOrAppId) にネストされているだけです。目的 これは、最初のリクエストが失敗した後に、SDK がまったく同じコードを自動的に実行できるようにするためです。

この機能は Senparc.Weixin.MP v12.1 でリリースされました。

WeChat パブリック プラットフォーム開発: AccessToken 自動管理メカニズムに関連するその他の記事については、PHP 中国語 Web サイトに注目してください。


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