


WeChat public platform development: AccessToken automatic management mechanism
In "WeChat Public Platform Development: General Interface Description", I introduced the method of obtaining AccessToken (general interface).
In the actual development process, all high-level interfaces need to provide AccessToken, so every time we call the high-level interface, we need to execute a method to obtain AccessToken, for example:
var accessToken = AccessTokenContainer.TryGetAccessToken(appId, appSecret);
Or after you have globally registered appId and appSecret, you can also do this:
var accessToken = AccessTokenContainer.GetAccessToken(_appId);
Then use this accessToken to enter the method of the advanced interface. For example, we can get the menu like this:
var result = CommonApi.GetMenu(accessToken);
Normally, this is already a very simple API calling process. But we don't want to stop there, we're going to shorten almost all API calls to one line.
While doing this, in addition to making the code simpler, we also have two wishes:
Let the API automatically handle the changed AccessToken (when multiple servers operate at the same time such as load balancing) In the case of a WeChat official account, the AccessToken may be refreshed externally, causing the local AccessToken to become invalid), and the final correct API result must be re-obtained and returned.
Does not change the current API calling method and is completely backward compatible.
Calling code
After modification, we can directly call the API with this line, and only need to provide an appId each time:
var result = CommonApi.GetMenu(appId);
Currently before execution , we need to register appId and appSecret globally as before:
AccessTokenContainer.Register(_appId, _appSecret);//全局只需注册一次,例如可以放在Global的Application_Start()方法中。
As you can see, the original accessToken is replaced by appId (the new version still supports entering accessToken), eliminating the process of obtaining accessToken. The specific process is explained below.
SDK source code implementation process
Previously, in order to automatically handle (unexpected) expired AccessToken, the SDK has provided the Senparc.Weixin.MP/AccessTokenHandlerWapper.Do() method. This upgrade renamed AccessTokenHandlerWapper.cs to ApiHandlerWapper.cs, abolished the Do() method, and added the TryCommonApi() method. The code is as follows:
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; } } }
The source code of the corresponding API originally looked like this:
/// <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; }
Now after using the TryCommonApi() method:
/// <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); }
We can observe several changes:
1. The original accessToken variable name was changed to accessTokenOrAppId (all related in the new version The interfaces will all change like this).
After modification, this parameter can be entered with accessToken (downward compatibility) or appId (no need to obtain accessToken). The SDK will automatically determine which type of parameter it belongs to based on the length of the string. There are 3 possible parameters provided:
a) appId. Using appId requires global registration of appId and appSecret in advance (as mentioned above). When the cached AccessToken is found to have expired during the API call, the SDK will automatically refresh the AccessToken and retry the API request to ensure that the correct result is returned. . If the appId has not been registered, an exception will be thrown.
b) accessToken. In this case, the original request method will be used. If the accessToken is invalid, an exception will be thrown directly without retrying.
c) null. When the accessTokenOrAppId parameter is null, the SDK will automatically obtain the first appId registered globally. If an application is only developed for a certain WeChat ID, this method can be used. When no appId is registered globally, an exception will be thrown.
2. The code for accessing the API in the original method has not been modified in any way. It is just nested into the method return ApiHandlerWapper.TryCommonApi(accessToken =>{...},accessTokenOrAppId) to delegate The purpose is to allow the SDK to automatically execute the exact same code after the first possible request fails.
This feature has been released in Senparc.Weixin.MP v12.1.
For more articles related to WeChat public platform development: AccessToken automatic management mechanism, please pay attention to the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function

SublimeText3 Chinese version
Chinese version, very easy to use

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.
