[Solved] 401 on POST requests, how to set up properly http service?

Question

Asked by squnk on December 23, 2021 (source).

I am trying to fetch data after successful login. I have cookie based auth on backend. I checked the login response and I see that the cookie is present in the headers. I am not sure why my requests are not going with cookie.

I keep getting this in my console, code for not authorized. I/flutter (21293): 401

class Session {
  Map<String, String> headers = {};

  Future<Map> get(String endpoint) async {
    http.Response response = await http.get(Uri.parse("$baseUrl$endpoint"), headers: headers);
    print(response.statusCode);
    updateCookie(response);
    return jsonDecode(response.body);
  }

  Future<http.Response> post(dynamic data, String endpoint) async {
    http.Response response = await http.post(Uri.parse("$baseUrl$endpoint"), body: json.decode(data), headers: headers);
    updateCookie(response);
    return response;
  }

  void updateCookie(http.Response response) {
    String? rawCookie = response.headers['set-cookie'];
    if (rawCookie != null) {
      int index = rawCookie.indexOf(';');
      headers['cookie'] =
      (index == -1) ? rawCookie : rawCookie.substring(0, index);
    }
  }
}

Tried to print rawCookie as well

I/flutter (21293): _api_key=SFMyNTY.g3QAAAABbQAAAAhpZGVudGl0eXQAAAAHZAAKX19zdHJ1Y3RfX2QAF0VsaXhpci5HYXRld2F5LklkZW50aXR5ZAAGYWN0aXZlZAAEdHJ1ZWQACWF2YXRhcl9pZG0AAAAkNTY4NWMwNTMtYThhMS00MDA5LWJhN2UtZmJkNTkyMjBhM2U1ZAAHY291bnRyeXQAAAAGZAAEZmxhZ20AAAAI8J-HtfCfh7FkAAppc29fbmFtZV8ybQAAAAJwbGQACmlzb19uYW1lXzNtAAAAA3BvbGQABG5hbWVtAAAABlBvbGFuZGQACG51bV9jb2RlbQAAAAM2MTZkAAVwb2ludHQAAAAEZAAKX19zdHJ1Y3RfX2QAEEVsaXhpci5HZW8uUG9pbnRkAAtjb29yZGluYXRlc2gCYRRhNGQACnByb3BlcnRpZXN0AAAAAGQABHNyaWRiAAAQ5mQAC2Rlc2NyaXB0aW9ubQAAAAF4ZAACaWRtAAAAJGM2ZTljY2Q0LTM4MmItNDEzZi04ODYyLTc2ZjM5ZTYxOGFiNGQABG5pY2ttAAAACHRlc3Rzc3Nz.80iQK3sUwPPVj1pkaZsKgMxQ4Lt8aW8-ndYbPSucGag; path=/; HttpOnly
I/flutter (21293): 200

Then I use it

class Items{
  Future<Map> fetchItems() async {
    final response = await Session().get("/user/items");
    return response;
  }
}

Answer

Question answered by Hzzkygcs (source).

I had the same problem. I resolved it by using dio and cookiejar instead of HTTP.

Add these dependencies in your pubspec.yaml:

dependencies:
  dio: ^4.0.4
  dio_cookie_manager: ^2.0.0
  cookie_jar: ^3.0.1

Here's an example to use dio:

var dio =  Dio(BaseOptions(
      connectTimeout: 10000,  // in ms
      receiveTimeout: 10000,
      sendTimeout: 10000,
      responseType: ResponseType.plain,
      followRedirects: false,
      validateStatus: (status) { return true; }
  ));   // some dio configurations

dio.interceptors.add(CookieManager(CookieJar()));

Response response = await dio.post(
          "http://example.com/login",
          data: FormData.fromMap(
             {
                'username': 'myUser',
                'password': 'myPassword',
             }
          ));  // cookies are automatically saved


Response nextResponse = await dio.post("http://example.com/user/items");

DART FLUTTER
SHARE: