Bläddra i källkod

增加微信AccessToken缓存与维护功能

ZHOU 1 år sedan
förälder
incheckning
cf5e57aec9

+ 33 - 0
Admin.NET/Admin.NET.Core/Job/WechatAccessTokenCheckJob.cs

@@ -0,0 +1,33 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Core;
+
+[JobDetail("job_WechatAccessTokenCheckJob", Description = "微信AccessToken有效性检查", GroupName = "default", Concurrent = false)]
+[PeriodSeconds(60, TriggerId = "trigger_WechatAccessTokenCheckJob", Description = "微信AccessToken有效性检查", RunOnStart = true)]
+public class WechatAccessTokenCheckJob : IJob
+{
+    private readonly IServiceScopeFactory _scopeFactory;
+    private readonly ILogger _logger;
+
+    public WechatAccessTokenCheckJob(IServiceScopeFactory scopeFactory, ILoggerFactory loggerFactory)
+    {
+        _scopeFactory = scopeFactory;
+        _logger = loggerFactory.CreateLogger(nameof(WechatAccessTokenCheckJob));
+    }
+
+
+    public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken)
+    {
+        using var serviceScope = _scopeFactory.CreateScope();
+
+        var factory = serviceScope.ServiceProvider.GetService<WechatApiClientFactory>();
+        await factory.CheckWechatAccessTokenAsync();
+        await factory.CheckWxOpenAccessTokenAsync();
+
+
+    }
+}

+ 117 - 1
Admin.NET/Admin.NET.Core/Service/Wechat/WechatApiHttpClient.cs

@@ -15,11 +15,14 @@ public partial class WechatApiClientFactory : ISingleton
 {
     private readonly IHttpClientFactory _httpClientFactory;
     public readonly WechatOptions _wechatOptions;
+    private readonly SysCacheService _sysCacheSrv;
 
-    public WechatApiClientFactory(IHttpClientFactory httpClientFactory, IOptions<WechatOptions> wechatOptions)
+
+    public WechatApiClientFactory(IHttpClientFactory httpClientFactory, IOptions<WechatOptions> wechatOptions, SysCacheService sysCacheSrv)
     {
         _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory));
         _wechatOptions = wechatOptions.Value ?? throw new ArgumentNullException(nameof(wechatOptions));
+        _sysCacheSrv = sysCacheSrv;
     }
 
     /// <summary>
@@ -81,4 +84,117 @@ public partial class WechatApiClientFactory : ISingleton
 
         return client;
     }
+
+
+
+
+    /// <summary>
+    /// 获取微信公众号AccessToken
+    /// </summary>
+    /// <returns></returns>
+    public async Task<string> TryGetWechatAccessTokenAsync()
+    {
+        var _sysCacheSrv = App.GetRequiredService<SysCacheService>();
+
+        if (!_sysCacheSrv.ExistKey($"WxAccessToken_{_wechatOptions.WechatAppId}") || string.IsNullOrEmpty(_sysCacheSrv.Get<string>($"WxAccessToken_{_wechatOptions.WechatAppId}")))
+        {
+            var client = CreateWechatClient();
+            var reqCgibinToken = new CgibinTokenRequest();
+            var resCgibinToken = await client.ExecuteCgibinTokenAsync(reqCgibinToken);
+            if (resCgibinToken.ErrorCode != (int)WechatReturnCodeEnum.请求成功)
+                throw Oops.Oh(resCgibinToken.ErrorMessage + " " + resCgibinToken.ErrorCode);
+            _sysCacheSrv.Set($"WxAccessToken_{_wechatOptions.WechatAppId}", resCgibinToken.AccessToken, TimeSpan.FromSeconds(resCgibinToken.ExpiresIn - 60));
+        }
+
+        return _sysCacheSrv.Get<string>($"WxAccessToken_{_wechatOptions.WechatAppId}");
+    }
+
+    /// <summary>
+    /// 获取微信小程序AccessToken
+    /// </summary>
+    /// <returns></returns>
+    public async Task<string> TryGetWxOpenAccessTokenAsync()
+    {
+        var _sysCacheSrv = App.GetRequiredService<SysCacheService>();
+
+        if (!_sysCacheSrv.ExistKey($"WxAccessToken_{_wechatOptions.WxOpenAppId}") || string.IsNullOrEmpty(_sysCacheSrv.Get<string>($"WxAccessToken_{_wechatOptions.WxOpenAppId}")))
+        {
+            var client = CreateWxOpenClient();
+            var reqCgibinToken = new CgibinTokenRequest();
+            var resCgibinToken = await client.ExecuteCgibinTokenAsync(reqCgibinToken);
+            if (resCgibinToken.ErrorCode != (int)WechatReturnCodeEnum.请求成功)
+                throw Oops.Oh(resCgibinToken.ErrorMessage + " " + resCgibinToken.ErrorCode);
+            _sysCacheSrv.Set($"WxAccessToken_{_wechatOptions.WxOpenAppId}", resCgibinToken.AccessToken, TimeSpan.FromSeconds(resCgibinToken.ExpiresIn - 60));
+        }
+
+        return _sysCacheSrv.Get<string>($"WxAccessToken_{_wechatOptions.WxOpenAppId}");
+    }
+
+
+    /// <summary>
+    /// 检查微信公众号AccessToken
+    /// </summary>
+    /// <returns></returns>
+    public async Task CheckWechatAccessTokenAsync()
+    {
+        var _sysCacheSrv = App.GetRequiredService<SysCacheService>();
+
+        if (string.IsNullOrEmpty(_wechatOptions.WechatAppId) || string.IsNullOrEmpty(_wechatOptions.WechatAppSecret)) return;
+
+        var req = new CgibinOpenApiQuotaGetRequest
+        {
+            AccessToken = await TryGetWxOpenAccessTokenAsync(),
+            CgiPath = "/cgi-bin/token"
+        };
+        var client = CreateWechatClient();
+        var res = await client.ExecuteCgibinOpenApiQuotaGetAsync(req);
+
+        var originColor = Console.ForegroundColor;
+        if (res.ErrorCode != (int)WechatReturnCodeEnum.请求成功)
+        {
+            _sysCacheSrv.Remove($"WxAccessToken_{_wechatOptions.WechatAppId}");
+            Console.ForegroundColor = ConsoleColor.Red;
+            Console.WriteLine("【" + DateTime.Now + "】" + _wechatOptions.WxOpenAppId + " 微信公众号令牌 无效");
+        }
+        else
+        {
+            Console.ForegroundColor = ConsoleColor.Magenta;
+            Console.WriteLine("【" + DateTime.Now + "】" + _wechatOptions.WxOpenAppId + " 微信公众号令牌 有效");
+        }
+        Console.ForegroundColor = originColor;
+    }
+
+
+    /// <summary>
+    /// 检查微信小程序AccessToken
+    /// </summary>
+    /// <returns></returns>
+    public async Task CheckWxOpenAccessTokenAsync()
+    {
+        var _sysCacheSrv = App.GetRequiredService<SysCacheService>();
+
+        if (string.IsNullOrEmpty(_wechatOptions.WxOpenAppId) || string.IsNullOrEmpty(_wechatOptions.WxOpenAppSecret)) return;
+
+        var req = new CgibinOpenApiQuotaGetRequest
+        {
+            AccessToken = await TryGetWxOpenAccessTokenAsync(),
+            CgiPath = "/cgi-bin/token"
+        };
+        var client = CreateWxOpenClient();
+        var res = await client.ExecuteCgibinOpenApiQuotaGetAsync(req);
+
+        var originColor = Console.ForegroundColor;
+        if (res.ErrorCode != (int)WechatReturnCodeEnum.请求成功)
+        {
+            _sysCacheSrv.Remove($"WxAccessToken_{_wechatOptions.WxOpenAppId}");
+            Console.ForegroundColor = ConsoleColor.Red;
+            Console.WriteLine("【" + DateTime.Now + "】" + _wechatOptions.WxOpenAppId + " 微信小程序令牌 无效");
+        }
+        else
+        {
+            Console.ForegroundColor = ConsoleColor.Magenta;
+            Console.WriteLine("【" + DateTime.Now + "】" + _wechatOptions.WxOpenAppId + " 微信小程序令牌 有效");
+        }
+        Console.ForegroundColor = originColor;
+    }
 }