0

I'm currently stuck on creating an api request with Flutter.

To explain the context, I need to recreate this request:

curl "url" --data "grant_type=password&client_id=x509" -E cert.pem

And to be more precise, the Content-Type of the request header must be of type x-www-form-encoded. Also, I am aware that using a client-side certificate is not secure, but this is an internal application.

My code :

  var cert = http.MultipartFile.fromBytes('x509',
      (await rootBundle.load('assets/keys/login.pem')).buffer.asInt8List(),
      filename: 'login.pem');

  Map<String, dynamic> headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
    'Accept': 'application/x-www-form-urlencoded'
  };

  var request = http.MultipartRequest(
      "POST",
      Uri.parse(
          url));
  headers['content-type'] = headers;
  request.fields['grant_type'] = 'password';
  request.fields['client_id'] = 'x509';
  request.files.add(cert);

  // Wait response and decode JSON.
  var response = await request.send();
  var responseData = await response.stream.toBytes();
  var result = jsonDecode(utf8.decode(responseData.toList()));

My problem :

Response code : 415
{"error":"RESTEASY003065: Cannot consume content type"}

With the screenshoot bellow, you'll see that the content-type is auto-set as a multipart/form-data. So I am looking for a way to overwrite it or a method to send my request please.

I guess overwriting it is bad because the api server will not handle the request correctly.

Informations on the request :

Request

EDIT : Now, I know that I can use context, sadly it's not available on Flutter web, do you have any idea ?

Weac
  • 124
  • 9
  • You don't seem to be linking the custom headers to your request. You wrote headers.. = headers. I suppose this is an error. You need to modify the request.headers field ! – Gaspard Merten Jul 28 '22 at 09:28
  • headers is a variable I declare on top of it, I tried to use a hardcoded string directly to be sure but it's not working. `request.headers.addAll({'Content-Type': 'application/x-www-form-urlencoded'});` `request.fields['client_id'] = 'x509';` `request.files.add(cert);` – Weac Jul 28 '22 at 10:42
  • You shouldn't be using the word multipart anywhere in your code. Simply replace most of your code with `await http.post(Uri.parse(url), body: aMapOfTheFields);` then there will be no need to set content type - it will be done for you. The whole thing with the pem file and the curl `-E` has to be handled completely separately. `-E` doesn't send the pem to the server as you appear to be doing, it uses it locally. Search "dart http send client cert" for how you should be doing this. – Richard Heap Jul 28 '22 at 11:15
  • `aMapOfTheFields` should simply be a map of the fields e.g. `'grant_type': 'password',` etc – Richard Heap Jul 28 '22 at 12:46
  • Currently trying to get this done using the search you made me do, but it end up with "Unsupported operation: default SecurityContext getter" http://www.noelshack.com/2022-30-4-1659013812-capture-d-ecran-2022-07-28-151007.png – Weac Jul 28 '22 at 13:12
  • Also, @RichardHeap I tried this method http://www.noelshack.com/2022-30-4-1659014014-capture-d-ecran-2022-07-28-151329.png But I end up with nowhere to put the file in. I should declare the context before the request ? – Weac Jul 28 '22 at 13:14
  • Are you using flutter web? If not, see: https://stackoverflow.com/questions/70741356/flutter-add-client-certificate-to-request-using-http-dart – Richard Heap Jul 28 '22 at 13:42
  • 1
    (Obviously, it would be pointless using a client side certificate in a web application as anyone would be able to steal your certificate.) – Richard Heap Jul 28 '22 at 13:45
  • I am actually using flutter web too... I know it's pointless to using a client side certificate and I have already put it forward but it's only a demo app and I have no others options. – Weac Jul 28 '22 at 14:56

0 Answers0