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、请求体格式等细节,快速找到不一致的地方。
验证步骤
- 先修复Authorization头的空格问题,测试请求是否成功
- 若仍返回403,添加Content-Type头重试
- 若问题依旧,添加模拟浏览器的User-Agent头
- 最后通过Postman生成的代码对比排查剩余差异
内容的提问来源于stack exchange,提问作者Joel Swakise TheDancer
相关产品推荐
相关产品推荐

