如何调试HttpPost请求,排查CSRF令牌导致的400错误原因?
问题描述
我有如下HttpPost动作:
[AllowAnonymous] [Route("api/Test")] [ApiController] public class TestController : ControllerBase { [Route("Something")] [HttpPost] //[IgnoreAntiforgeryToken] public async Task<IActionResult> Something() { return Ok(new { Result = true }); } }
当启用[IgnoreAntiforgeryToken]标签时,接口可正常工作。这表明通过Postman发送POST请求时需携带CSRF令牌,我尝试在请求头或x-www-form-urlencoded格式的请求体中配置__RequestVerificationToken,且确保令牌已更新,但仍收到400错误响应:
{ "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1", "title": "Bad Request", "status": 400, "traceId": "00-4b7d669686a083fbba09be86b6841e42-847918b0b6ca656b-00" }
我尝试通过以下中间件调试请求体:
public void Configure(IApplicationBuilder app) { app.Use(async (context, next) => { var initialBody = context.Request.Body; using (var bodyReader = new System.IO.StreamReader(context.Request.Body)) { string body = await bodyReader.ReadToEndAsync(); Console.WriteLine(body); context.Request.Body = new System.IO.MemoryStream(Encoding.UTF8.GetBytes(body)); await next.Invoke(); context.Request.Body = initialBody; } //await next.Invoke(); }); }
但未发现异常,请问该如何找到导致此400错误的原因?
排查与解决步骤
- 检查Antiforgery中间件配置:确认
ConfigureServices中是否正确配置了Antiforgery服务,比如services.AddAntiforgery(options => { options.HeaderName = "X-CSRF-TOKEN"; });,确保配置的令牌名称和请求中携带的一致。 - 验证令牌配对规则:Antiforgery验证需要请求中的令牌与Cookie里的
__RequestVerificationToken配对,只传其中一个会直接失败。要确保Postman请求同时携带了正确的Cookie和对应的令牌值。 - 核对请求内容类型与参数名:如果在请求体传令牌,必须保证
Content-Type为application/x-www-form-urlencoded,且参数名严格为__RequestVerificationToken(大小写敏感);如果用请求头传递,要和中间件配置的HeaderName完全匹配。 - 启用详细调试日志:在
appsettings.json中调整日志级别,获取Antiforgery验证的具体失败原因:
日志会明确提示是令牌不匹配、Cookie缺失还是其他验证问题。{ "Logging": { "LogLevel": { "Default": "Debug", "Microsoft.AspNetCore.Antiforgery": "Debug" } } } - 调整调试中间件顺序:把你写的请求体调试中间件放在
app.UseRouting()和app.UseAuthorization()之前,确保它在Antiforgery验证拦截请求前就读取到完整的请求内容。 - 检查Postman的Cookie状态:确认Postman中是否保存了服务器返回的
__RequestVerificationTokenCookie,这个Cookie是令牌验证的必要组成部分,必须和请求中的令牌值对应。
内容的提问来源于stack exchange,提问作者Erick Asto Oblitas
相关产品推荐
相关产品推荐

