Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Share tokens and tickets with IAbpWeChatSharableCache #71

Merged
merged 1 commit into from
Jan 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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.2.0</Version>
<Version>2.3.0</Version>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>EasyAbp Team</Authors>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Threading.Tasks;
using System.Threading.Tasks;
using EasyAbp.Abp.WeChat.Common.Infrastructure.AccessToken;
using EasyAbp.Abp.WeChat.Common.SharedCache.StackExchangeRedis.Settings;
using Microsoft.Extensions.Caching.Distributed;
Expand All @@ -10,14 +9,14 @@

namespace EasyAbp.Abp.WeChat.Common.SharedCache.StackExchangeRedis.Infrastructure.AccessToken;

public class SharedStackExchangeRedisAccessTokenCache : IAccessTokenCache, ITransientDependency
public class SharedStackExchangeRedisAbpWeChatSharableCache : IAbpWeChatSharableCache, ITransientDependency
{
public static string CachePrefix { get; set; } = "WeChatTokens:";
public static string SettingName { get; set; } = SharedCacheStackExchangeRedisSettings.RedisConfiguration;

private readonly ISettingProvider _settingProvider;

public SharedStackExchangeRedisAccessTokenCache(ISettingProvider settingProvider)
public SharedStackExchangeRedisAbpWeChatSharableCache(ISettingProvider settingProvider)
{
_settingProvider = settingProvider;
}
Expand All @@ -29,14 +28,18 @@ public virtual async Task<string> GetOrNullAsync(string key)
return await redisCache.GetStringAsync(await GetKeyAsync(key));
}

public virtual async Task SetAsync(string key, string value)
public virtual async Task SetAsync(string key, string value, DistributedCacheEntryOptions options)
{
var redisCache = await CreateAbpRedisCacheAsync();

await redisCache.SetStringAsync(await GetKeyAsync(key), value, new DistributedCacheEntryOptions
if (value is null)
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(115)
});
await redisCache.RemoveAsync(await GetKeyAsync(key));
}
else
{
await redisCache.SetStringAsync(await GetKeyAsync(key), value, options);
}
}

protected virtual Task<string> GetKeyAsync(string key)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
using Volo.Abp.Caching;
Expand All @@ -7,11 +6,11 @@
namespace EasyAbp.Abp.WeChat.Common.Infrastructure.AccessToken;

[Dependency(TryRegister = true)]
public class DefaultAccessTokenCache : IAccessTokenCache, ITransientDependency
public class DefaultAbpWeChatSharableCache : IAbpWeChatSharableCache, ITransientDependency
{
protected IDistributedCache<string> DistributedCache { get; }

public DefaultAccessTokenCache(IDistributedCache<string> distributedCache)
public DefaultAbpWeChatSharableCache(IDistributedCache<string> distributedCache)
{
DistributedCache = distributedCache;
}
Expand All @@ -21,11 +20,8 @@ public virtual Task<string> GetOrNullAsync(string key)
return DistributedCache.GetAsync(key);
}

public virtual Task SetAsync(string key, string value)
public virtual Task SetAsync(string key, string value, DistributedCacheEntryOptions options)
{
return DistributedCache.SetAsync(key, value, new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(115)
});
return DistributedCache.SetAsync(key, value, options);
}
}
Original file line number Diff line number Diff line change
@@ -1,35 +1,39 @@
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
using Newtonsoft.Json.Linq;
using Volo.Abp.DependencyInjection;

namespace EasyAbp.Abp.WeChat.Common.Infrastructure.AccessToken
{
public class DefaultAccessTokenProvider : IAccessTokenProvider, ITransientDependency
{
private readonly IAccessTokenCache _accessTokenCache;
private readonly IAbpWeChatSharableCache _abpWeChatSharableCache;
private readonly IHttpClientFactory _httpClientFactory;

public DefaultAccessTokenProvider(
IAccessTokenCache accessTokenCache,
IAbpWeChatSharableCache abpWeChatSharableCache,
IHttpClientFactory httpClientFactory)
{
_accessTokenCache = accessTokenCache;
_abpWeChatSharableCache = abpWeChatSharableCache;
_httpClientFactory = httpClientFactory;
}

public virtual async Task<string> GetAsync(string appId, string appSecret)
{
var cacheKey = await GetCacheKeyAsync(appId);

var token = await _accessTokenCache.GetOrNullAsync(cacheKey);
var token = await _abpWeChatSharableCache.GetOrNullAsync(cacheKey);

if (token.IsNullOrWhiteSpace())
{
token = await RequestAccessTokenAsync(appId, appSecret);

await _accessTokenCache.SetAsync(cacheKey, token);
await _abpWeChatSharableCache.SetAsync(cacheKey, token, new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(115)
});
}

return token;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Caching.Distributed;

namespace EasyAbp.Abp.WeChat.Common.Infrastructure.AccessToken;

public interface IAccessTokenCache
public interface IAbpWeChatSharableCache
{
Task<string> GetOrNullAsync([NotNull] string key);

Task SetAsync([NotNull] string key, [CanBeNull] string value);
Task SetAsync([NotNull] string key, [CanBeNull] string value, DistributedCacheEntryOptions options);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using EasyAbp.Abp.WeChat.Official.Options;
using Microsoft.Extensions.Caching.Distributed;
using Newtonsoft.Json.Linq;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;

namespace EasyAbp.Abp.WeChat.Official.JsTickets
Expand All @@ -17,45 +16,42 @@ public class DefaultJsTicketProvider : IJsTicketProvider, ITransientDependency
private readonly IHttpClientFactory _httpClientFactory;
private readonly IAccessTokenProvider _accessTokenProvider;
private readonly IAbpWeChatOptionsProvider<AbpWeChatOfficialOptions> _optionsProvider;
private readonly IDistributedCache<string> _distributedCache;
private readonly IAbpWeChatSharableCache _cache;

public DefaultJsTicketProvider(
IHttpClientFactory httpClientFactory,
IAccessTokenProvider accessTokenProvider,
IAbpWeChatOptionsProvider<AbpWeChatOfficialOptions> optionsProvider,
IDistributedCache<string> distributedCache)
IAbpWeChatSharableCache cache)
{
_httpClientFactory = httpClientFactory;
_accessTokenProvider = accessTokenProvider;
_optionsProvider = optionsProvider;
_distributedCache = distributedCache;
_cache = cache;
}

public virtual async Task<string> GetTicketJsonAsync(string appId, string appSecret)
{
var options = await _optionsProvider.GetAsync(appId);
var cacheKey = await GetCacheKeyAsync(appId);

var accessToken = await _accessTokenProvider.GetAsync(appId, appSecret);
var cachedValue = await _cache.GetOrNullAsync(cacheKey);

return await _distributedCache.GetOrAddAsync(await GetJsTicketAsync(options),
async () =>
{
var client = _httpClientFactory.CreateClient(AbpWeChatConsts.HttpClientName);
var requestUrl =
$"https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={accessToken}&type=jsapi";
if (cachedValue.IsNullOrEmpty())
{
cachedValue = await RequestTicketAsync(appId, appSecret);

return await (await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, requestUrl)))
.Content.ReadAsStringAsync();
},
() => new DistributedCacheEntryOptions
await _cache.SetAsync(cacheKey, cachedValue, new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(115)
});
}

return cacheKey;
}

protected virtual async Task<string> GetJsTicketAsync(IAbpWeChatOptions options)
protected virtual Task<string> GetCacheKeyAsync(string appId)
{
return $"WeChatJsTicket:{options.AppId}";
return Task.FromResult($"WeChatJsTicket:{appId}");
}

public virtual async Task<string> GetTicketAsync(string appId, string appSecret)
Expand All @@ -65,5 +61,17 @@ public virtual async Task<string> GetTicketAsync(string appId, string appSecret)

return jObj.SelectToken("$.ticket")!.Value<string>();
}

protected virtual async Task<string> RequestTicketAsync(string appId, string appSecret)
{
var accessToken = await _accessTokenProvider.GetAsync(appId, appSecret);

var client = _httpClientFactory.CreateClient(AbpWeChatConsts.HttpClientName);
var requestUrl =
$"https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={accessToken}&type=jsapi";

return await (await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, requestUrl)))
.Content.ReadAsStringAsync();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
using EasyAbp.Abp.WeChat.Common.Infrastructure.AccessToken;
using Microsoft.Extensions.Caching.Distributed;
using Volo.Abp.DependencyInjection;

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

public class AuthorizerAccessTokenCache : IAuthorizerAccessTokenCache, ITransientDependency
{
protected IAccessTokenCache AccessTokenCache { get; }
protected IAbpWeChatSharableCache AbpWeChatSharableCache { get; }

public AuthorizerAccessTokenCache(IAccessTokenCache accessTokenCache)
public AuthorizerAccessTokenCache(IAbpWeChatSharableCache abpWeChatSharableCache)
{
AccessTokenCache = accessTokenCache;
AbpWeChatSharableCache = abpWeChatSharableCache;
}

public virtual async Task<string> GetOrNullAsync(string componentAppId, string authorizerAppId)
{
return await AccessTokenCache.GetOrNullAsync(await GetCacheKeyAsync(componentAppId, authorizerAppId));
return await AbpWeChatSharableCache.GetOrNullAsync(await GetCacheKeyAsync(componentAppId, authorizerAppId));
}

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

protected virtual async Task<string> GetCacheKeyAsync(string componentAppId, string authorizerAppId) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Threading.Tasks;
using Volo.Abp.Caching;
using EasyAbp.Abp.WeChat.Common.Infrastructure.AccessToken;
using Microsoft.Extensions.Caching.Distributed;
using Volo.Abp.DependencyInjection;

namespace EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.AuthorizerRefreshToken;
Expand All @@ -12,21 +13,22 @@ namespace EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.AuthorizerRefreshTo
[Dependency(TryRegister = true)]
public class CacheAuthorizerRefreshTokenStore : IAuthorizerRefreshTokenStore, ITransientDependency
{
private readonly IDistributedCache<string> _cache;
private readonly IAbpWeChatSharableCache _cache;

public CacheAuthorizerRefreshTokenStore(IDistributedCache<string> cache)
public CacheAuthorizerRefreshTokenStore(IAbpWeChatSharableCache cache)
{
_cache = cache;
}

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

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

protected virtual async Task<string> GetCacheKeyAsync(string componentAppId, string authorizerAppId) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
using System;
using System.Net.Http;
using System.Threading.Tasks;
using EasyAbp.Abp.WeChat.Common.Infrastructure.AccessToken;
using EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.ApiRequests;
using EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.Models;
using EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.VerifyTicket;
using Microsoft.Extensions.Caching.Distributed;
using Volo.Abp;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;

namespace EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.ComponentAccessToken;

public class DefaultComponentAccessTokenProvider : IComponentAccessTokenProvider, ITransientDependency
{
private readonly IDistributedCache<string> _distributedCache;
private readonly IAbpWeChatSharableCache _cache;
private readonly IComponentVerifyTicketStore _componentVerifyTicketStore;
private readonly IWeChatThirdPartyPlatformApiRequester _apiRequester;

public DefaultComponentAccessTokenProvider(
IDistributedCache<string> distributedCache,
IAbpWeChatSharableCache cache,
IComponentVerifyTicketStore componentVerifyTicketStore,
IWeChatThirdPartyPlatformApiRequester apiRequester)
{
_distributedCache = distributedCache;
_cache = cache;
_componentVerifyTicketStore = componentVerifyTicketStore;
_apiRequester = apiRequester;
}
Expand All @@ -32,12 +32,24 @@ public virtual async Task<string> GetAsync(string componentAppId, string compone
Check.NotNullOrWhiteSpace(componentAppId, nameof(componentAppId));
Check.NotNullOrWhiteSpace(componentAppSecret, nameof(componentAppSecret));

return await _distributedCache.GetOrAddAsync($"ComponentAccessToken:{componentAppId}",
async () => await RequestComponentAccessTokenAsync(componentAppId, componentAppSecret),
() => new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(115)
});
var key = $"ComponentAccessToken:{componentAppId}";

var cachedValue = await _cache.GetOrNullAsync(key);

if (cachedValue.IsNullOrEmpty())
{
cachedValue = await RequestComponentAccessTokenAsync(componentAppId, componentAppSecret);

await _cache.SetAsync(
key,
cachedValue,
new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(115)
});
}

return cachedValue;
}

protected virtual async Task<string> RequestComponentAccessTokenAsync(
Expand Down