From 76ff60e793f7a0133d23fe4d749f59ea214a9005 Mon Sep 17 00:00:00 2001 From: zzh <1368735060@qq.com> Date: Thu, 2 Jul 2026 12:15:25 +0800 Subject: [PATCH] =?UTF-8?q?fix(wechat):=20=E9=AA=8C=E7=AD=BE=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E6=94=AF=E6=8C=81=20HEAD=20=E5=B9=B6=E9=81=BF?= =?UTF-8?q?=E5=85=8D=E9=85=8D=E7=BD=AE=E5=BC=82=E5=B8=B8=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E9=9D=9E=20200?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 微信后台/探活对 HEAD 会收到 405;读取 wechat_mp 配置异常时改为 HTTP 200 + error,与 WMS 行为一致。 Co-authored-by: Cursor --- .../WeChatRouteIntegrationTests.cs | 11 +++++++ .../Auth/AuthService.WeChatMp.cs | 31 +++++++++++++++++-- .../WeChat/WeChatMpCallbackSupport.cs | 10 ++++-- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/SimpleAdmin.Api.IntegrationTests/WeChatRouteIntegrationTests.cs b/src/SimpleAdmin.Api.IntegrationTests/WeChatRouteIntegrationTests.cs index 205ac8b..2564cf3 100644 --- a/src/SimpleAdmin.Api.IntegrationTests/WeChatRouteIntegrationTests.cs +++ b/src/SimpleAdmin.Api.IntegrationTests/WeChatRouteIntegrationTests.cs @@ -46,6 +46,17 @@ public class WeChatRouteIntegrationTests (await response.Content.ReadAsStringAsync()).Should().Be(echostr); } + [Fact] + public async Task WeChatValidateLegacy_Head_ShouldReturn200() + { + await using var host = await SimpleAdminApiTestHost.CreateAsync(configureServices: ConfigureWeChatFallback); + + var request = new HttpRequestMessage(HttpMethod.Head, "/apiwechat/verification"); + var response = await host.Client.SendAsync(request); + + response.StatusCode.Should().Be(HttpStatusCode.OK); + } + private static void ConfigureWeChatFallback(IServiceCollection services) { services.PostConfigure(options => diff --git a/src/SimpleAdmin.Api/Auth/AuthService.WeChatMp.cs b/src/SimpleAdmin.Api/Auth/AuthService.WeChatMp.cs index df57e47..91b67f0 100644 --- a/src/SimpleAdmin.Api/Auth/AuthService.WeChatMp.cs +++ b/src/SimpleAdmin.Api/Auth/AuthService.WeChatMp.cs @@ -27,6 +27,7 @@ public partial class AuthService /// [AllowAnonymous] [HttpGet("/apiwechat/verification")] + [HttpHead("/apiwechat/verification")] [Produces("text/plain")] [ApiExplorerSettings(GroupName = "WeChat")] public async Task WeChatValidateLegacyAsync( @@ -36,8 +37,34 @@ public partial class AuthService [FromQuery] string? echostr, CancellationToken cancellationToken = default) { - var options = await WeChatMpConfigProvider.GetAsync(cancellationToken); - return WeChatMpCallbackSupport.Validate(options, signature, timestamp, nonce, echostr); + if (string.Equals( + httpContextAccessor.HttpContext?.Request.Method, + HttpMethods.Head, + StringComparison.OrdinalIgnoreCase)) + { + return WeChatMpCallbackSupport.HeadOk(); + } + + return await WeChatValidateCoreAsync(signature, timestamp, nonce, echostr, cancellationToken); + } + + private async Task WeChatValidateCoreAsync( + string? signature, + string? timestamp, + string? nonce, + string? echostr, + CancellationToken cancellationToken) + { + try + { + var options = await WeChatMpConfigProvider.GetAsync(cancellationToken); + return WeChatMpCallbackSupport.Validate(options, signature, timestamp, nonce, echostr); + } + catch (Exception ex) + { + WeChatLogger.LogWarning(ex, "微信公众号验签读取配置失败"); + return WeChatMpCallbackSupport.PlainError(); + } } /// diff --git a/src/SimpleAdmin.Api/WeChat/WeChatMpCallbackSupport.cs b/src/SimpleAdmin.Api/WeChat/WeChatMpCallbackSupport.cs index 4d3d126..d5ecbc2 100644 --- a/src/SimpleAdmin.Api/WeChat/WeChatMpCallbackSupport.cs +++ b/src/SimpleAdmin.Api/WeChat/WeChatMpCallbackSupport.cs @@ -17,7 +17,7 @@ internal static class WeChatMpCallbackSupport // 微信服务器要求 HTTP 200 + 纯文本 echostr,不可抛 BusinessException(会变成 JSON 非 200) if (string.IsNullOrWhiteSpace(options.Token)) { - return PlainText("error"); + return PlainError(); } if (string.IsNullOrWhiteSpace(signature) @@ -25,13 +25,19 @@ internal static class WeChatMpCallbackSupport || string.IsNullOrWhiteSpace(nonce) || string.IsNullOrWhiteSpace(echostr)) { - return PlainText("error"); + return PlainError(); } var valid = WeChatSignatureHelper.Validate(options.Token, timestamp, nonce, signature); return PlainText(valid ? echostr : "error"); } + /// 微信或探活可能发 HEAD,须返回 200(WMS/Spring 默认支持)。 + public static ContentResult HeadOk() => + new() { Content = string.Empty, ContentType = "text/plain; charset=utf-8", StatusCode = StatusCodes.Status200OK }; + + public static ContentResult PlainError() => PlainText("error"); + public static async Task HandleMessageAsync( WeChatMpOptions options, IWeChatEventHandler eventHandler,