flutterhttpgraphqlsslpinning

Implementing SSL Pinning with Flutter GraphQL


I need help implementing SSL pinning on Flutter using graphql_flutter and http_certificate_pinning. Here's my code implementation so far:

import 'package:graphql_flutter/graphql_flutter.dart';

import 'package:http_certificate_pinning/http_certificate_pinning.dart';

class Service {
  final List<String> _allowedSHAFingerprints;

  late GraphQLClient _gqlClient;
  GraphQLClient get gqlClient => _gqlClient;

  late SecureHttpClient _secureHttpClient;
  SecureHttpClient get secureHttpClient => _secureHttpClient;

  Service(this._allowedSHAFingerprints) {
    _secureHttpClient = SecureHttpClient.build(_allowedSHAFingerprints);

    final httpLink = HttpLink(
      'https://dummy.com/graphql/',
      httpClient: _secureHttpClient,
    );

    _gqlClient = GraphQLClient(
      link: httpLink,
      cache: GraphQLCache(),
    );
  }
}

The problem is gqlClient always returned connection success (secure) even if allowedSHAFingerprints is not valid. I tried HTTP GET method using secureHTTPClient and it works perfectly. Am I doing something wrong here?

Here's how I called it:

Future<void> _gqlCall() async {
    try {
      final secureClient = GetIt.I<Service>().gqlClient;
      final options = QueryOptions(
        document: gql(homePageQuery),
      );
      final result = await secureClient.query(options);
      if (!result.hasException) {
        _showSnackbar('GQL Success');
      } else {
        throw Exception();
      }
    } on Exception catch (_) {
      _showSnackbar('GQL Fail');
    }
  }

Below code is working as I expected:

Future<void> _apiCall() async {
    try {
      final url = Uri.parse('https://dummy.com/ping');

      final result = await GetIt.I<Service>().secureHttpClient.get(url);

      if (result.statusCode == 200) {
        _showSnackbar('API Success');
      } else {
        throw Exception();
      }
    } on Exception catch (_) {
      _showSnackbar('API Fail');
    }
  }

Solution

  • Finally solved this problem.

    I'm using dio and another library called gql_dio_link

    Here's my implementation of Service class now:

    import 'package:dio/dio.dart';
    import 'package:gql_dio_link/gql_dio_link.dart';
    import 'package:graphql_flutter/graphql_flutter.dart';
    import 'package:http_certificate_pinning/http_certificate_pinning.dart';
    
    class Service {
      final List<String> _allowedSHAFingerprints;
    
      late GraphQLClient _secureGqlClient;
      GraphQLClient get secureGqlClient => _secureGqlClient;
    
      late Dio _secureDioClient;
      Dio get secureDioClient => _secureDioClient;
    
      Service(this._allowedSHAFingerprints) {
        _secureDioClient = Dio(BaseOptions(baseUrl: 'https://dummy.com'))
          ..interceptors.add(CertificatePinningInterceptor(
              allowedSHAFingerprints: _allowedSHAFingerprints));
    
        final link = Link.from([
          DioLink(
            '/graphql',
            client: _secureDioClient,
          ),
        ]);
    
        _secureGqlClient = GraphQLClient(
          link: link,
          cache: GraphQLCache(),
        );
      }
    }