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

Flutter Dart使用Bearer Token请求API报401 同参数Swift请求正常

问题根因与修复方案

以下是该场景下按出现概率排序的常见诱因,对应修复方式可直接套用:

1. http库form编码默认值与头声明不匹配

这是该类问题最高发的坑:Dart官方http包对form请求的编码逻辑不会读取你手动在headers里写的charset配置——当你给post()传入Map<String,String>类型的body、且未显式指定encoding参数时,库会固定用ISO-8859-1(Latin-1)编码请求体,和你手动写的charset=UTF-8声明完全不一致。
只要请求体里存在任何非ASCII字符(中文、全角符号、Unicode特殊字符等),服务端收到的内容就是乱码,绝大多数API网关、WAF遇到这类头声明和实际编码不匹配的请求,会直接拦截返回401,根本不会走到后续的Bearer Token校验流程。

修复方法

显式给post方法传入utf8编码参数,强制库按UTF-8处理请求体:

var response = await client.post(
  url, 
  headers: headers, 
  body: body,
  encoding: utf8,
);

如果改完仍有异常,可以直接把请求体手动编码成字节数组传入,彻底绕开库的默认编码逻辑:

import 'dart:convert';
// ...
final encodedBody = utf8.encode(Uri(queryParameters: body).query);
var response = await client.post(
  url,
  headers: headers,
  body: encodedBody,
);

2. Client自动携带了历史无效Cookie

http.Client()默认会持久化同域名下所有历史请求的Cookie,并且在后续请求里自动携带。如果你在拿到有效Bearer Token之前,用同一个Client实例发过登录失败、未授权的请求,残留的过期Session、匿名标识Cookie会被自动带到本次请求中。
大量服务端的鉴权优先级是Cookie高于Authorization头,只要请求带了Cookie就优先校验Cookie合法性,Cookie无效直接返回401,完全不会校验你传入的Bearer Token。Swift端如果用的是临时会话、默认关闭Cookie持久化,就不会触发这个问题。

修复方法

要么每次发鉴权请求新建一个干净的Client实例,要么在headers里强制清空Cookie:

var headers = <String, String>{
  // 原有Accept、Content-Type、Authorization配置保持不变
  "Cookie": "",
};

3. Token携带了肉眼不可见的冗余字符

即使你确认两端Token的文本内容完全一致,Dart端解析登录响应时,很容易把Token值前后的换行符、转义引号、空白字符一起截入变量——这类不可见字符无法通过肉眼排查,但拼入Authorization头后会直接导致Token校验失败。

修复方法

拼接头之前对Token做清洗:

// 去除前后空白、首尾可能被误解析进来的包裹引号
final validToken = rawToken.trim().replaceAll(RegExp(r'^"|"$'), '');
headers["Authorization"] = "Bearer $validToken";

4. 自动添加的隐式请求头触发服务端拦截

http库会自动给请求添加若干你没有手动配置的头,最常见的是Accept-Encoding: gzip、User-Agent: Dart/<版本号> (dart:io)。部分配置严格的企业级API会校验User-Agent白名单,遇到非预期的请求头会直接拦截返回401。

排查方法

本地起一个临时HTTP调试服务,把Dart端、Swift端发出的完整请求头、请求体逐字段对比,将Dart端自动添加的差异头手动覆盖为和Swift端完全一致的值即可。


内容的提问来源于stack exchange,提问作者Wrog

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 22:09:49