Flutter'da Firebase App Check (Turkish)

Firebase App Check'i Flutter uygulamalarınızda nasıl kullanacağınızı öğrenin.

Flutter’da Firebase App Check

Image source: Protecting Apps and APIs: A Deep Dive into Firebase App Check and Play Integrity at Chingari

App check, Firebase servislerini, Google Cloud servislerini veya kendi yazmış olduğunuz custom backend kaynağınızın kötüye kullanılmasını önlemeye çalışıp uygulamanızın güvenliğini arttırmakta size yardımcı olan bir servistir.

Daha fazla bilgi edinmek için https://firebase.google.com/docs/app-check adresini ziyaret edebilirsiniz.

Bu yazıda kullanacağımız paketler

dependencies:
  dio: ^5.4.1
  firebase_app_check: ^0.2.1+14
  firebase_core: ^2.25.4

Firebase App Check Kurulumu

Paketlerimizi uygulamamıza ekledikten sonra yeni bir firebase projesi oluşturup android ve iOS projelerini uygulamamıza dahil ediyoruz. Dahil ettikten sonra uygulamamızdaki main.dart dosyasını aşağıdaki şekilde değiştiriyoruz.

import 'package:example_app_check/firebase_options.dart';
import 'package:firebase_app_check/firebase_app_check.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  await FirebaseAppCheck.instance.activate(
      appleProvider: AppleProvider.debug,
      androidProvider: AndroidProvider.debug);

  runApp(const MyApp());
}

Uygulamamızı iOS ortamında çalıştırdığımızda console’da debug mode için üretilen bir debug token göreceksiniz.

Firebase App Check Debug Token: 2C394DBB-9724-4B70-8207-7CF878E520EE

Android ortamında çalıştırdığımızda ise bu şekilde olacaktır.

D/com.google.firebase.appcheck.debug.internal.DebugAppCheckProvider(14914): 
Enter this debug secret into the allow list in the
Firebase Console for your project: 88750bd0-854c-454c-96b5-920d3ea0b639

Token Oluşturma

Firebase App Check üzerinden bir token generate etmek istediğimizde aşağıdaki şekilde getToken methodunu çağırabiliriz.

String? token = await FirebaseAppCheck.instance.getToken();

Methodu çağırdığımız zaman uygulama şöyle bir hata verecektir.

FirebaseException ([firebase_app_check/unknown] com.google.firebase.FirebaseException: Error returned from API. code: 403 body: App attestation failed.)

Bu hatanın sebebi Firebase App Check tarafından verified edilmemiş bir cihaz tarafından çağrıldığı için hata vermektedir. O yüzden yukarıda hem android hem iOS için generate edilmiş debug token’ları firebase console üzerinden eklememiz gerekmekte.

Firebase Console

Firebase console üzerinden app check section’daki üç noktada bulunan manage debug tokens’a tıklayarak iOS ve android için generate edilmiş debug token’ları ekleyebiliriz.

Debug Token Ekleme

Debug tokenları ekledikten sonra getToken methodunu çağırarak console üzerinden token’ı loglayarak görebiliriz.

log('Token: $token');

Loga baktığımızda aşağıdaki gibi generate edilmiş token’ı görebiliriz.

Token:eyJraWQiOiJYcEhKU0EiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1N…

Debug ortamında token oluşturduktan sonra production ortamı için nasıl token oluşturabildiğimize bakalım.

Android: Play Integrity Provider

Android ortamı için kullanabileceğimiz 2 provider var:

  1. SafetyNet
  2. Play Integrity

SafetyNet, deprecated olmuş bir provider olup Haziran 2024’ten sonra tamamen kapatılacaktır

Bu yüzden biz uygulamamızda Play Integrity provider’ını kullanarak geliştirme yapacağız.

Uygulamamıza Play Integrity Provider’ını Dahil Etme

Öncellikle firebase console açıp app check section’daki android kısmından Play Integrity tıklıyoruz.

Play Integrity Setup

Burada sizden SHA-256 certificate fingerprint istiyor.

SHA-256 Certificate

Bunun için Google Play Console üzerinden dilerseniz var olan uygulamanızın dilerseniz de yeni bir uygulama oluşturup SHA-256 certificate kopyalayıp Firebase Console’a ekliyoruz.

Google Play Console

Firebase Console ekledikten sonra başarılı bir şekilde Play Integrity provider’ını aktif etmiş olduk.

iOS: Device Check ve App Attest Providers

iOS ortamı için de kullanabileceğimiz 2 provider var:

  1. Device Check
  2. App Attest

Uygulamada her iki provider’ı da kullanabiliriz. Firebase tarafından tercih edilen App Attest provider olup sadece iOS 14.0 ve daha fazlası sürümlerde geçerli olduğu için App Test, geçerli olmayan cihazlarda Device Check provider’ını kullanacağız.

Uygulamamıza Device Check ve App Attest Provider’ını Dahil Etme

Firebase App Check section’daki Device Check tıkladığımızda, Device Check aktif edebilmemiz için Auth key, Key ID, Team ID bilgilerini girmemiz gerekmekte.

Device Check Setup

Auth Key generate edebilmemiz için bir developer apple hesabı gerekiyor. Hesabınız var ise https://developer.apple.com/account/resources/authkeys/list sayfasını gidip bir Auth Key oluşturuyoruz.

Apple Developer

Create a key butonuna tıklayıp Key Name dilediğinizi yazabilirsiniz. Device Check opsiyionun enable edip continue butonuyla devam ettikten sonra register butonuna basarak Auth Key generate ediyoruz.

Create Auth Key

Auth Key generate edildikten sonra bu key’i bir seferlik indirebiliyorsunuz. Bu yüzden güvenli bir yerde saklanmanız sizler için faydalı olacaktır.

Download Auth Key

Auth Key indirdikten sonra indirdiğiniz sayfada Key Id, Team Id(developer hesabınızın yanında) kopyalayıp Auth Key ile beraber Firebase Console’daki Device Check kısmına ekliyoruz.

Add to Firebase

Ekledikten sonra Device Check ve App Attest providerlarını başarılı bir şekilde aktif etmiş olduk.

Xcode’da App Attest Ayarları

Firebase Console tarafında providerları aktif ettikten sonra Xcode üzerinden App Attest’i ayarlamamız gerekiyor.

Bunun için gerekli adımlar:

  1. Uygulamamızı Xcode üzerinde açıyoruz.
  2. (+ Capability) butonuna tıklayarak, App Attest ekliyoruz.

Add App Attest

Ekledikten sonra uygulamamızı tekrardan başlatırken

await FirebaseAppCheck.instance.activate(
      appleProvider: AppleProvider.deviceCheck,
      androidProvider:
          kDebugMode ? AndroidProvider.debug : AndroidProvider.playIntegrity);

appleProvider’ı Device Check olarak belirlediğimizde loglar’da başarılı bir şekilde token üretildiğini göreceksiniz.

  1. App Attest provider’nın çalışması için .entitlements dosyasındaki App Attest Environment’ı production olarak set etmemiz gerekiyor.

Entitlements

Set ettikten sonra appleProvider’ı App Attest olarak belirlediğimizde token başarılı bir şekilde üretilecektir.

await FirebaseAppCheck.instance.activate(
      appleProvider: kDebugMode
          ? AppleProvider.debug
          : AppleProvider.appAttestWithDeviceCheckFallback,
      androidProvider:
          kDebugMode ? AndroidProvider.debug : AndroidProvider.playIntegrity);

Örnek Senaryo

Uygulamamızdaki kullanmış olduğumuz custom backend kaynağının kötüye kullanılmasını engellemek için şöyle bir senaryo gerçekleştirebiliriz.

Custom backend’e gelen her bir request’in, uygulamamız tarafından yapıldığını belirlemesi için, request’in header’ına ürettiğimiz token’ı sağlamamız gerekiyor. Bunun için http client paketlerinden olan dio paketinden yararlanarak bir interceptor yazacağız. Böylece her bir request’in header’ına otomatik olarak token’ı eklemiş olacağız.

class AppCheckInterceptor extends Interceptor {
  @override
  Future<void> onRequest(
    RequestOptions options,
    RequestInterceptorHandler handler,
  ) async {
    String? appCheckToken = await FirebaseAppCheck.instance.getToken();

    options.headers['X-Firebase-AppCheck'] = appCheckToken;

    return handler.next(options);
  }
}

Custom backend, gelen her bir request’in header’ına bakarak firebase’deki uygulamadan gelip gelmediğini verify ederek uygulama güvenliğini arttıracaktır.

Not: Android uygulamanızın app check özelliğini production ortamında çalışıp çalışmadığını anlayabilmeniz için uygulamayı Google Play Store üzerinden indirmeniz gerekmektedir. Uygulamayı daha yayınlamadıysanız Internal Test kullanarak test edebilirsiniz.


Okuduğunuz için teşekkür ederim, umarım faydalı olur. Sorularınız olursa LinkedIn üzerinden sorabilirsiniz.

Uygulamanın kaynak kodlarına aşağıdaki linkten ulaşabilirsiniz: GitHub - hasankarli/example_app_check