Skip to content

Commit

Permalink
Merge pull request #45 from EasyAbp/authorizer-accesstoken-cache
Browse files Browse the repository at this point in the history
Introduce `IAuthorizerAccessTokenCache`
  • Loading branch information
gdlcf88 committed Dec 14, 2022
2 parents 83d978a + e1b732d commit 65e3c3a
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 24 deletions.
2 changes: 1 addition & 1 deletion common.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>2.0.0-preview.4</Version>
<Version>2.0.0-preview.5</Version>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>EasyAbp Team</Authors>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;

namespace EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.ThirdPartyPlatform.AccessToken;

public class AuthorizerAccessTokenCache : IAuthorizerAccessTokenCache, ITransientDependency
{
protected IDistributedCache<string> Cache { get; }

public AuthorizerAccessTokenCache(IDistributedCache<string> cache)
{
Cache = cache;
}

public virtual async Task<string> GetAsync(string componentAppId, string authorizerAppId)
{
return await Cache.GetAsync(await GetCacheKeyAsync(componentAppId, authorizerAppId));
}

public virtual async Task SetAsync(string componentAppId, string authorizerAppId, string accessToken)
{
await Cache.SetAsync(
await GetCacheKeyAsync(componentAppId, authorizerAppId),
accessToken,
new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(115)
});
}

protected virtual async Task<string> GetCacheKeyAsync(string componentAppId, string authorizerAppId) =>
$"AuthorizerAccessToken:{componentAppId}:{authorizerAppId}";
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,38 +21,42 @@ namespace EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.ThirdPartyPlatform.Acce
public class HybridAccessTokenProvider : IAccessTokenProvider, ISingletonDependency
{
private readonly IServiceProvider _serviceProvider;
private readonly IAuthorizerAccessTokenCache _cache;
private readonly IAuthorizerRefreshTokenStore _authorizerRefreshTokenStore;
private readonly IWeChatThirdPartyPlatformOptionsResolver _weChatThirdPartyPlatformOptionsResolver;
private readonly IComponentAccessTokenProvider _componentAccessTokenProvider;
private readonly IWeChatOpenPlatformApiRequester _weChatOpenPlatformApiRequester;
private readonly IDistributedCache<string> _distributedCache;

public HybridAccessTokenProvider(
IServiceProvider serviceProvider,
IAuthorizerAccessTokenCache cache,
IAuthorizerRefreshTokenStore authorizerRefreshTokenStore,
IWeChatThirdPartyPlatformOptionsResolver weChatThirdPartyPlatformOptionsResolver,
IComponentAccessTokenProvider componentAccessTokenProvider,
IWeChatOpenPlatformApiRequester weChatOpenPlatformApiRequester,
IDistributedCache<string> distributedCache)
IWeChatOpenPlatformApiRequester weChatOpenPlatformApiRequester)
{
_serviceProvider = serviceProvider;
_cache = cache;
_authorizerRefreshTokenStore = authorizerRefreshTokenStore;
_weChatThirdPartyPlatformOptionsResolver = weChatThirdPartyPlatformOptionsResolver;
_componentAccessTokenProvider = componentAccessTokenProvider;
_weChatOpenPlatformApiRequester = weChatOpenPlatformApiRequester;
_distributedCache = distributedCache;
}

public virtual async Task<string> GetAccessTokenAsync(string appId, string appSecret)
{
if (appSecret.IsNullOrWhiteSpace())
{
return await _distributedCache.GetOrAddAsync($"CurrentAccessToken:{appId}",
async () => await RequestAuthorizerAccessTokenAsync(appId),
() => new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(115)
});
var options = await _weChatThirdPartyPlatformOptionsResolver.ResolveAsync();

var accessToken = await _cache.GetAsync(options.AppId, appId);

if (accessToken.IsNullOrWhiteSpace())
{
await _cache.SetAsync(options.AppId, appId, await RequestAuthorizerAccessTokenAsync(options, appId));
}

return accessToken;
}

var defaultAccessTokenProvider = _serviceProvider.GetRequiredService<DefaultAccessTokenProvider>();
Expand All @@ -64,21 +68,20 @@ public virtual async Task<string> GetAccessTokenAsync(string appId, string appSe
/// 获取/刷新接口调用令牌
/// https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/2.0/api/ThirdParty/token/api_authorizer_token.html
/// </summary>
protected virtual async Task<string> RequestAuthorizerAccessTokenAsync(string appId)
protected virtual async Task<string> RequestAuthorizerAccessTokenAsync(
IWeChatThirdPartyPlatformOptions options, string appId)
{
var thirdPartyPlatformOptions = await _weChatThirdPartyPlatformOptionsResolver.ResolveAsync();

const string authorizerTokenApiUrl = "https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token";

var url = await AppendComponentAccessTokenAsync(authorizerTokenApiUrl, thirdPartyPlatformOptions);
var url = await AppendComponentAccessTokenAsync(authorizerTokenApiUrl, options);

var response = await _weChatOpenPlatformApiRequester.RequestAsync<AuthorizerTokenResponse>(
url, HttpMethod.Post, new AuthorizerTokenRequest
{
ComponentAppId = thirdPartyPlatformOptions.AppId,
ComponentAppId = options.AppId,
AuthorizerAppId = appId,
AuthorizerRefreshToken =
await _authorizerRefreshTokenStore.GetOrNullAsync(thirdPartyPlatformOptions.AppId, appId)
await _authorizerRefreshTokenStore.GetOrNullAsync(options.AppId, appId)
});

if (response.AuthorizerAccessToken.IsNullOrWhiteSpace())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Threading.Tasks;
using JetBrains.Annotations;

namespace EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.ThirdPartyPlatform.AccessToken;

public interface IAuthorizerAccessTokenCache
{
Task<string> GetAsync([NotNull] string componentAppId, [NotNull] string authorizerAppId);

Task SetAsync([NotNull] string componentAppId, [NotNull] string authorizerAppId, [NotNull] string accessToken);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;

Expand Down Expand Up @@ -28,11 +26,7 @@ public virtual async Task<string> GetOrNullAsync(string componentAppId, string a

public virtual async Task SetAsync(string componentAppId, string authorizerAppId, string authorizerRefreshToken)
{
await _cache.SetAsync(await GetCacheKeyAsync(componentAppId, authorizerAppId), authorizerRefreshToken,
new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(115)
});
await _cache.SetAsync(await GetCacheKeyAsync(componentAppId, authorizerAppId), authorizerRefreshToken);
}

protected virtual async Task<string> GetCacheKeyAsync(string componentAppId, string authorizerAppId) =>
Expand Down

0 comments on commit 65e3c3a

Please sign in to comment.