Closed CooperLiu closed 5 years ago
谢谢反馈!
在TryUpdateAuthorizationInfo方法内,authorizerBag会被重新获取一次:
代码上来看应该是对的,不知道您那边是否方便输出一下日志?比如实际每次变更的过期时间等等?
日志:
2017-02-16 14:00:00.5566 Zmind.Scrm.WeChat.WechatMessageService 1.进入开放平台:[wx2a10323fe09421ab],获取授权公众号:[wx9dc86883b02dc326],Access Token。
=================================================
=================================================
2017-02-16 14:00:00.6191 Zmind.Scrm.WeChat.WechatMessageService 3.发现授权信息已经过期,过期时间:2017/2/16 11:47:45。
=================================================
2017-02-16 14:00:00.6659 Zmind.Scrm.WeChat.WechatMessageService 4.重新(TryGetAuthorizerAccessToken)获取授权的Token:tw4v875q--D9d3e042n4I4UY7PMNwsYWThlDq9AxjRsNIl03g9koTvkmzQtMroaYwS3WWZN-7g2J-7mhoU0zdyC-r3iWu_Tt22cO5V3Dp3bgxAYWtUwqe9KzbYMYXx2kFQNgAGDTEB,缓存中的Token:tw4v875q--D9d3e042n4I4UY7PMNwsYWThlDq9AxjRsNIl03g9koTvkmzQtMroaYwS3WWZN-7g2J-7mhoU0zdyC-r3iWu_Tt22cO5V3Dp3bgxAYWtUwqe9KzbYMYXx2kFQNgAGDTEB,是否一致:True
=================================================
2017-02-16 14:00:03.9160 Zmind.Scrm.WeChat.WechatMessageService 5.重新调用RefreshAPI获取AccessToken:4fx5SPFpvuaQaU77h2nOZcUW6lGGfC-hnjZ-14AFy1emPxj_rkEtaTo11o_T3s9z3AEE5odh5JVeYR2pfqcJkkWJ619CMmdd14wenQE8KGvpxEz5IBNADsGVqVOObPWpRJCjALDKCV
================================================= 【WechatOpenAccount.AppId】开放平台ComponentAppId ,【appId】授权公众号AuthorizerAppId
`Logger.Info($"1.进入开放平台:[{WechatOpenAccount.AppId}],获取授权公众号:[{appId}],Access Token。");
var cacheObj = AuthorizerContainer.TryGetItem(appId);
Logger.Info($"2.获取缓存授权信息:{cacheObj.ToJsonString()}");
if (cacheObj.AuthorizationInfoExpireTime <= DateTime.Now)
{
Logger.Info($"3.发现授权信息已经过期,过期时间:{cacheObj.AuthorizationInfoExpireTime}。");
var token = AuthorizerContainer.TryGetAuthorizerAccessToken(WechatOpenAccount.AppId, appId);
var isSame = token == cacheObj.AuthorizationInfo.authorizer_access_token;
Logger.Info($"4.重新(TryGetAuthorizerAccessToken)获取授权的Token:{token}" +
$",缓存中的Token:{cacheObj.AuthorizationInfo.authorizer_access_token}" +
$",是否一致:{isSame}");
if (isSame)
{
var componentAppId = WechatOpenAccount.AppId;
var componentVerifyTicket = ComponentContainer.TryGetComponentVerifyTicket(componentAppId);
var componentAccessToken = ComponentContainer.GetComponentAccessToken(componentAppId, componentVerifyTicket);
//获取新的AuthorizerAccessToken
var refreshToken = ComponentContainer.GetAuthorizerRefreshTokenFunc(appId);
var refreshResult = AuthorizerContainer.RefreshAuthorizerToken(componentAccessToken, componentAppId, appId,
refreshToken);
cacheObj.AuthorizationInfo.authorizer_access_token = refreshResult.authorizer_access_token;
cacheObj.AuthorizationInfo.authorizer_refresh_token = refreshResult.authorizer_refresh_token;
cacheObj.AuthorizationInfo.expires_in = refreshResult.expires_in;
cacheObj.AuthorizationInfoExpireTime = ApiUtility.GetExpireTime(refreshResult.expires_in);
AuthorizerContainer.TryUpdateAuthorizationInfo(componentAppId, appId,
refreshResult.authorizer_access_token, refreshResult.authorizer_refresh_token,
refreshResult.expires_in);
Logger.Info($"5.重新调用RefreshAPI获取AccessToken:{refreshResult.authorizer_access_token}");
}
}
Logger.Info($"授权服务号:{cacheObj.FullAuthorizerInfoResult.authorizer_info.nick_name}" +
$",AppId:[{appId}]" +
$",获取APIToken:{cacheObj.AuthorizationInfo.authorizer_access_token}" +
$",有效期:{cacheObj.AuthorizationInfoExpireTime}。");
return cacheObj.AuthorizationInfo.authorizer_access_token;`
不好意思,看了两遍,没有明白这个和您说的不能更新缓存有什么联系?从哪一条日志可以看出来呢?
我理解的AuthorizerContainer.TryGetAuthorizerAccessToken方法应该是:如果缓存的AuthorizerAccessToken过期,会自动调用RefreshToken接口来更新AccessToken,然后更新缓存的AuthorizerAccessToken的过期时间。
我原来实现的只是调用了 AuthorizerContainer.TryGetAuthorizerAccessToken(WechatOpenAccount.AppId, appId);
此方法来获取AuthorizerAccessToken,但是每次都还是获取到已经过期的AccessToken,后来,加上日志查看,发现缓存里的AuthorizerAccessToken就算过期也未更新,不知道是不是issues?还是我对此理解的不够?
贴出来的Code中的IsSame 是比较缓存中的Token,和调用AuthorizerContainer.TryGetAuthorizerAccessToken(WechatOpenAccount.AppId, appId);
之后,获取到Token是否一致,结果是一致的,而且都是过期的
第四条日志:
2017-02-16 14:00:00.6659 Zmind.Scrm.WeChat.WechatMessageService 4.重新(TryGetAuthorizerAccessToken)获取授权的Token:tw4v875q--D9d3e042n4I4UY7PMNwsYWThlDq9AxjRsNIl03g9koTvkmzQtMroaYwS3WWZN-7g2J-7mhoU0zdyC-r3iWu_Tt22cO5V3Dp3bgxAYWtUwqe9KzbYMYXx2kFQNgAGDTEB,缓存中的Token:tw4v875q--D9d3e042n4I4UY7PMNwsYWThlDq9AxjRsNIl03g9koTvkmzQtMroaYwS3WWZN-7g2J-7mhoU0zdyC-r3iWu_Tt22cO5V3Dp3bgxAYWtUwqe9KzbYMYXx2kFQNgAGDTEB,是否一致:True
我是不是能这样理解:你的用意是判断更新之后的Token,和更新之前的是否相同,结果是相同的,所以就可以确定缓存没有被更新?
这里面有几种可能我大致分析一下:
由于提高分布式缓存读写(主要是写)效率,我们提供了一个队列来处理缓存自动更新,因此实际上是有一个微小的时间差的(平均1秒)。当然我们也提供了强制立即更新的方法。
因此如果要测试是否真的更新,建议在更新之后让线程停止2秒。
假设已经这么做,那么:
上述更改是有效的
cacheObj 在判断isSame之前需要重新获取一次,因为Reids中的对象是序列化后储存的,更新之后的实例是不一样的。
谢谢回复。
我使用的Redis的缓存组件。简单说我的初衷是使用TryGetAuthorizerAccessToken
来获取授权公众公众号的apiAccessToken,但是实际应用下来(在Token过期时),获取到的Token仍然为过期的Token。所以,问题是如何简单的获取到授权公众号apiAccessToken,让Sdk来管理过期机制?
@JeffreySu 我的理解: https://github.com/JeffreySu/WeiXinMPSDK/blob/1f71194a4ca6bb6bb8717f6cf54500bd355e05cc/src/Senparc.Weixin.Open/Senparc.Weixin.Open/Containers/AuthorizerContainer.cs#L272 这里的 AuthorizationInfo属性未被更新,所以拿到的authorizer_access_token仍是过期的。
嗯,有道理,我跟进看一下,谢谢!
@wangzixin1113 @CooperLiu 已经更新到 Open v2.8.3(master分支下) 请查看是否有解决问题。欢迎反馈,谢谢!
问题描述
项目背景: 使用微信公众平台授权给微信开放平台,进行多公众号授权运营。 我尝试使用以下方法获取授权的公众号的AccessToken,发现不会自动管理AccessToken的过期时间。
获取授权公众号Access Token方法
发现在此出更新时,不会更新局部变量authorizerBag
是不是应该吧局部变量authorizerBag 传入TryUpdateAuthorizationInfo?
发现问题的模块
模块对应的.net版本
开发环境
缓存环境