mTLS API calls

Database & APIs
Resolved

This is not an issue, but a solution for enabling mTLS authentication and encryption for FluttewrFlow API calls. This might help someone else, hence the posting

What have you tried so far?

Apply these steps for mTLS:

1.       Open file /lib/backed/api_requests/api_manager.dart

2.       Add the below imports

//***************** added *************************

import 'package:http/io_client.dart';

//***************** end  *************************

 

3.       Update the function requestwithbody

4.       Add the code in red. Ensure all requests are https in the/lib/backed/api_requests/api_calls.dart file

static Future<ApiCallResponse> requestWithBody(
  ApiCallType type,
  String apiUrl,
  Map<String, dynamic> headers,
  Map<String, dynamic> params,
  String? body,
  BodyType? bodyType,
  bool returnBody,
  bool encodeBodyUtf8,
  bool decodeUtf8,
  bool alwaysAllowBody, {
  http.Client? client,
}) async {
  assert(
    {ApiCallType.POST, ApiCallType.PUT, ApiCallType.PATCH}.contains(type) ||
        (alwaysAllowBody && type == ApiCallType.DELETE),
    'Invalid ApiCallType $type for request with body',
  );
  final postBody =
      createBody(headers, params, body, bodyType, encodeBodyUtf8);

  if (bodyType == BodyType.MULTIPART) {
    return multipartRequest(type, apiUrl, headers, params, returnBody,
        decodeUtf8, alwaysAllowBody);
  }
//************* added code *********************
  var clientCertificatePath = 'assets/certificates/client_cert.pem';
  var clientKeyPath = 'assets/certificates/client_key.pem';
  var caCertificatePath = 'assets/certificates/ca_cert.pem';

  final context = SecurityContext.defaultContext;

  // Load the certificates key
  ByteData clientCertificate = await rootBundle.load(clientCertificatePath);
  ByteData privateKey = await rootBundle.load(clientKeyPath);
  String rootCACertificate = await rootBundle.loadString(caCertificatePath);

  //Load certificates into current context
  context.setTrustedCertificatesBytes(utf8.encode(rootCACertificate));
  context.useCertificateChainBytes(clientCertificate.buffer.asUint8List());
  context.usePrivateKeyBytes(privateKey.buffer.asUint8List());

  // modify context as needed
  final httpClient = HttpClient(context: context);
  final client = IOClient(httpClient);
//*************** end of added code *********************


  final requestFn = {
    ApiCallType.POST: client != null ? client.post : http.post,
    ApiCallType.PUT: client != null ? client.put : http.put,
    ApiCallType.PATCH: client != null ? client.patch : http.patch,
    ApiCallType.DELETE: client != null ? client.delete : http.delete,
  }[type]!;

  final response = await requestFn(Uri.parse(apiUrl),
      headers: toStringMap(headers), body: postBody);
  return ApiCallResponse.fromHttpResponse(response, returnBody, decodeUtf8);
}

 

5.       Open the file api_calls.dart

6.       Replace all occurrences of http:// with https://

7.       Finally the pubsec.yaml in the project root needs to be updated to include the certificate asset folder. Add assets/certificates/ to the below configuration

# To add assets to your application, add an assets section, like this:
assets:
  - assets/fonts/
  - assets/images/
  - assets/videos/
  - assets/audios/
  - assets/lottie_animations/
  - assets/rive_animations/
  - assets/pdfs/
  - assets/certificates/

Did you check FlutterFlow's Documentation for this topic?
Yes
4
1 reply