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

Flutter请求返回403状态码 同令牌Postman可正常请求

Flutter HTTP请求返回403,但Postman调用正常(使用相同Bearer令牌)

问题场景

使用相同的Bearer令牌调用登录接口时,Postman能正常返回JSON响应,但Flutter代码执行后始终得到403状态码。

Flutter请求代码

Future<void> signIn() async {
  Map<String, dynamic> body = {
    "email": emailcontroller.text,
    "password": passwordcontroller.text,
  };

  try {
    setState(() {
      isLoading = true;
    });
    Map<String, String> head = {
      "Authorization": "Bearer  ZjdkMjZhNTJmMzZkNTYwNzI0YTE5MGUwODVjM2UwMjI=",
    };

    var url = Uri.parse(
        'https://staging.mam-laka.com/api/?resource=user&action=login');
    var responsee = await http.post(url, headers: head, body: jsonEncode(body));

    print("Status code: ${responsee.statusCode}");
    print("Response headers: ${responsee.headers}");
    print("Response body: ${responsee.body}");

    Map data = jsonDecode(responsee.body);
    print(data);
  } catch (e) {
    print("Error: $e");
  } finally {
    setState(() {
      isLoading = false;
    });
  }
}

收到的403响应详情

flutter: Status code: 403
flutter: Response headers: {connection: keep-alive, access-control-allow-origin: *, transfer-encoding: chunked, date: Sat, 02 Nov 2024 08:08:22 GMT, content-encoding: gzip, server-timing: cfL4;desc="?proto=TCP&rtt=174408&sent=4&recv=7&lost=0&retrans=0&sent_bytes=2814&recv_bytes=658&delivery_rate=11287&cwnd=250&unsent_bytes=0&cid=ec74b12a68b946f8&ts=488&x=0", 
cf-cache-status: DYNAMIC, 
report-to: {"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=WKSXtShxltV1X3mhbHNvFbBrmMaUkgbKcWZcMpIPWUlet%2Bg%2BA0HpEmQKv56BgeNqFxhEVb%2FCbkZZHei4CFaSVW3ojQwqdIFf0NTHGYjJRufpZyD7PhskNlPzML3TiVhBrDRcBSNE6g%3D%3D"}],"group":"cf-nel","max_age":604800}, 
access-control-max-age: 3600, 
content-type: application/json; charset=UTF-8, 
server: cloudflare, 
access-control-allow-headers: Content-Type, 
Access-Control-Allow-Headers, 
Authorization, 
X-Requested-With, 
alt-svc: h3=":443"; ma=86400, 
access-control-allow-methods: POST, 
nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}, 
cf-ray: 8dc2a2e1de660b5c-AMS}

排查与修复方案

1. 修复Authorization头的空格问题

你的Authorization头中Bearer后有两个空格,而Postman中通常是单个空格。多数服务器对令牌格式校验严格,多余空格会导致令牌解析失败,直接返回403。

修改代码:

"Authorization": "Bearer ZjdkMjZhNTJmMzZkNTYwNzI0YTE5MGUwODVjM2UwMjI=",

2. 添加Content-Type请求头

你用jsonEncode(body)发送JSON格式请求体,但未设置Content-Type: application/json。Postman会自动添加该头,但Flutter的http.post不会默认携带,服务器可能因无法解析请求体拒绝访问。

修改headers:

Map<String, String> head = {
  "Authorization": "Bearer ZjdkMjZhNTJmMzZkNTYwNzI0YTE5MGUwODVjM2UwMjI=",
  "Content-Type": "application/json",
};

3. 模拟浏览器User-Agent绕过Cloudflare拦截

响应头显示服务器使用Cloudflare,它会对非浏览器请求触发人机验证。Postman默认的User-Agent会被识别为合法请求,而Flutter默认的User-Agent(如Dart/3.x)会被拦截。

添加User-Agent头:

Map<String, String> head = {
  "Authorization": "Bearer ZjdkMjZhNTJmMzZkNTYwNzI0YTE5MGUwODVjM2UwMjI=",
  "Content-Type": "application/json",
  "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
};

4. 对比Postman生成的代码定位差异

在Postman中点击「Code」按钮,选择「Dart - http」生成代码,对比你的代码与生成代码的headers、请求体格式等细节,快速找到不一致的地方。

验证步骤

  1. 先修复Authorization头的空格问题,测试请求是否成功
  2. 若仍返回403,添加Content-Type头重试
  3. 若问题依旧,添加模拟浏览器的User-Agent头
  4. 最后通过Postman生成的代码对比排查剩余差异

内容的提问来源于stack exchange,提问作者Joel Swakise TheDancer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 14:05:53