You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flurl中如何在同一会话中先后发起Get、POST请求解决CSRF校验失败问题

问题根因

你的代码存在两个核心问题直接导致CSRF校验失败:

  1. 未保持同一会话:CSRF令牌是和当前用户会话绑定的,Postman默认会自动持久化请求返回的Cookie、后续请求自动携带,因此可以正常调用。你当前两次请求是独立会话,POST请求使用的是新会话,和获取令牌的GET请求会话不匹配,即使令牌值正确也会校验失败。
  2. 请求头名称格式错误:标准的CSRF请求头名称为X-CSRF-Token(中划线分隔),你当前代码用的是下划线X_CSRF_Token,部分服务端对请求头名称的分隔符、大小写敏感,无法识别下划线格式的请求头。

修正方案

你使用的是Flurl HTTP库,只需要保证两次请求共享同一个IFlurlClient实例、开启Cookie持久化,同时修正请求头名称即可:

1. 初始化共享会话客户端

// 在全局/类级别声明,保证两次请求用同一个客户端,维持会话
private readonly IFlurlClient sapClient = new FlurlClient(SA_BaseUrl)
    .WithBasicAuth("UserName", "Password")
    .WithCookies(); // 开启自动Cookie持久化,保持同一会话

2. 修正GET请求获取令牌代码

var result = await sapClient.Request()
            .AppendPathSegments("ProdOrderConfSet")
            .WithHeader("Accept","application/json")
            // 修正请求头名称为中划线格式
            .WithHeader("X-CSRF-Token", "fetch")
            .GetAsync();

IReadOnlyNameValueList<string> headers = result.Headers;
// 增加忽略大小写匹配,避免服务端返回的Header大小写不一致导致取值失败
string X_CSRF_Token = headers.FirstOrDefault(h => h.Name.Equals("x-csrf-token", StringComparison.OrdinalIgnoreCase)).Value;

3. 修正POST请求代码

var result2 = await sapClient.Request()
                .AppendPathSegments("ProdOrderConfSet")   
                .WithHeader("Accept","application/json")
                .WithHeader("Content-Type", "application/json")
                // 修正请求头名称为中划线格式
                .WithHeader("X-CSRF-Token", X_CSRF_Token)
                .PostJsonAsync(workStep)
                .ReceiveJson<DANTESAP_ProdWorkStep>();

可选校验点

如果修改后仍有问题,可以抓包对比Postman和C#代码的请求差异,重点核对:

  • POST请求携带的Cookie是否和GET请求返回的会话Cookie完全一致
  • 请求头X-CSRF-Token的取值、格式是否和GET响应返回的完全一致

内容的提问来源于stack exchange,提问作者H. Saffour

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 20:06:06