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

Flutter对接Laravel后端出现419(页面过期)错误排查求助

解决Flutter调用Laravel Sanctum登录接口返回419错误的问题

你的代码存在三个核心问题,导致Laravel返回419(CSRF验证失败):

1. 未携带会话Cookie到登录请求

Laravel Sanctum的CSRF验证依赖会话Cookie(不仅仅是X-XSRF-TOKEN请求头)。你只提取了XSRF-TOKEN的值,但没有将请求sanctum/csrf-cookie返回的Cookie传递到后续登录请求中。Postman会自动管理Cookie,所以能正常请求,而Flutter的http包默认不会自动保存和携带Cookie。

2. 手动拆分Cookie的逻辑不可靠

你直接通过字符串拆分set-cookie头提取XSRF-TOKEN的方式存在两个问题:

  • set-cookie可能包含多个Cookie值,拆分逻辑可能取错内容
  • XSRF-TOKEN在Cookie中是经过URL编码的,直接提取会导致值不匹配

3. 登录请求的Body未正确编码

你直接将user Map作为body参数传递,但http.post的body如果要发送JSON格式,需要用jsonEncode()编码,否则后端无法正确解析参数。


修复方案(推荐使用CookieJar自动管理Cookie)

使用cookie_jar包自动处理Cookie的存储和携带,避免手动操作的错误:

步骤1:添加依赖到pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  http: ^0.13.5
  cookie_jar: ^4.0.1

步骤2:修改代码

import 'dart:convert';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:http/http.dart' as http;
import 'package:http/io_client.dart';

// 全局CookieJar实例,用于管理Cookie
final cookieJar = CookieJar();

Future getXsrf() async {
  try {
    Uri url = Uri.parse('http://10.0.2.2:80/sanctum/csrf-cookie');
    final httpClient = HttpClient()..followRedirects = false;
    final ioClient = IOClient(httpClient);
    
    final response = await ioClient.get(url);
    // 将返回的Cookie存入CookieJar
    cookieJar.saveFromResponse(url, response.cookies);
    
    if (response.statusCode != 204) {
      throw Exception('获取CSRF Token失败:${response.statusCode}');
    }
  } catch (error) {
    throw Exception('获取CSRF Token出错:$error');
  }
}

Future<UserModel> login(Map<String, dynamic> user) async {
  try {
    await getXsrf();
    Uri url = Uri.parse('http://10.0.2.2:80/user/login');
    
    final httpClient = HttpClient()..followRedirects = false;
    // 从CookieJar加载对应URL的Cookie,添加到请求中
    final cookies = await cookieJar.loadForRequest(url);
    for (var cookie in cookies) {
      httpClient.cookies.add(cookie);
    }
    
    final ioClient = IOClient(httpClient);
    final response = await ioClient.post(
      url,
      headers: {'Content-type': 'application/json'},
      body: jsonEncode(user), // 正确编码JSON请求体
    );
    
    if (response.statusCode == 200) {
      // 假设UserModel有fromJson构造函数
      return UserModel.fromJson(jsonDecode(response.body));
    } else {
      throw Exception('登录失败:${response.statusCode}');
    }
  } catch (error) {
    throw Exception('登录出错:$error');
  }
}

额外注意事项

  • 确保Laravel的config/sanctum.php中stateful配置包含你的Flutter应用的域名/IP(比如['10.0.2.2', 'localhost'])
  • 如果是真机测试,需要把10.0.2.2换成你的电脑局域网IP,同时确保手机和电脑在同一网络下

内容的提问来源于stack exchange,提问作者El Hombre Sin Nombre

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:13:15