Implementing SSL Pinning with Flutter GraphQL

491 views Asked by At

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');
    }
  }
1

There are 1 answers

0
Serpentarius On BEST ANSWER

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(),
    );
  }
}