Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.

Melakukan Autentikasi Menggunakan Apple dan C ++

Anda dapat mengizinkan pengguna melakukan autentikasi dengan Firebase melalui ID Apple pengguna tersebut menggunakan Firebase SDK untuk menjalankan alur login OAuth 2.0 end-to-end.

Sebelum memulai

Untuk login menggunakan Apple, pertama-tama konfigurasikan Login dengan Apple di situs developer Apple, lalu aktifkan Apple sebagai penyedia login untuk project Firebase Anda.

Bergabunglah dengan Program Developer Apple

Login dengan Apple hanya dapat dikonfigurasi oleh anggota Program Developer Apple.

Mengonfigurasi Login dengan Apple

Login dengan Apple harus diaktifkan dan dikonfigurasi dengan benar di project Firebase Anda. Konfigurasi ini bervariasi di berbagai platform Android dan iOS. Pelajari bagian "Mengonfigurasi Login dengan Apple" di panduan iOS dan/atau Android sebelum melanjutkan.

Mengaktifkan Apple sebagai penyedia login

  1. Di Firebase console, buka bagian Auth. Pada tab Metode login, aktifkan penyedia Apple.
  2. Konfigurasikan setelan penyedia Login dengan Apple:
    1. Jika Anda hanya menerapkan aplikasi di iOS, Anda dapat mengosongkan kolom ID Layanan, ID Tim Apple, kunci pribadi, dan ID kunci.
    2. Untuk dukungan di perangkat Android:
      1. Tambahkan Firebase ke project Android Anda. Pastikan untuk mendaftarkan tanda tangan SHA-1 aplikasi saat Anda menyiapkan aplikasi di Firebase console.
      2. Di Firebase console, buka bagian Auth. Pada tab Metode login, aktifkan penyedia Apple. Tentukan ID Layanan yang Anda buat di bagian sebelumnya. Selain itu, di bagian konfigurasi alur kode OAuth, tentukan ID Tim Apple, kunci pribadi, dan ID kunci yang Anda buat di bagian sebelumnya.

Mematuhi persyaratan data anonim Apple

Login dengan Apple memberi pengguna opsi untuk menganonimkan data miliknya, termasuk alamat email, saat login. Pengguna yang memilih opsi ini memiliki alamat email dengan domain privaterelay.appleid.com. Saat Anda menggunakan Login dengan Apple di aplikasi, Anda harus mematuhi kebijakan atau persyaratan developer yang berlaku dari Apple terkait ID Apple yang dianonimkan ini.

Hal ini termasuk memperoleh persetujuan pengguna yang diperlukan sebelum Anda mengaitkan informasi identitas pribadi apa pun langsung dengan ID Apple yang dianonimkan. Penggunaan Firebase Authentication dapat meliputi tindakan-tindakan berikut:

  • Menautkan alamat email ke ID Apple yang dianonimkan atau sebaliknya.
  • Menautkan nomor telepon ke ID Apple yang dianonimkan atau sebaliknya
  • Menautkan kredensial sosial non-anonim (Facebook, Google, dsb.) ke ID Apple yang dianonimkan atau sebaliknya.

Daftar di atas tidak lengkap. Baca Perjanjian Lisensi Program Developer Apple di bagian Keanggotaan akun developer untuk memastikan aplikasi Anda memenuhi persyaratan Apple.

Mengakses class firebase::auth::Auth

Class Auth adalah gateway untuk semua panggilan API.
  1. Tambahkan file header Auth dan Aplikasi:
    #include "firebase/app.h"
    #include "firebase/auth.h"
    
  2. Pada kode inisialisasi Anda, buat class firebase::App.
    #if defined(__ANDROID__)
      firebase::App* app =
          firebase::App::Create(firebase::AppOptions(), my_jni_env, my_activity);
    #else
      firebase::App* app = firebase::App::Create(firebase::AppOptions());
    #endif  // defined(__ANDROID__)
    
  3. Dapatkan class firebase::auth::Auth untuk firebase::App Anda. Terdapat fungsi pemetaan one-to-one antara App dan Auth.
    firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);
    

Menangani alur login dengan Firebase SDK

Proses Login dengan Apple bervariasi di berbagai platform iOS dan Android.

Di iOS

Melakukan autentikasi pengguna dengan Firebase melalui Objective-C SDK Login dengan Apple yang dipanggil dari kode C++ Anda.

  1. Untuk setiap permintaan proses login, buat string acak — “nonce” —yang akan Anda gunakan untuk memastikan bahwa token ID yang Anda dapatkan khusus diberikan sebagai tanggapan atas permintaan autentikasi aplikasi Anda. Langkah ini penting untuk mencegah terjadinya serangan replay.

      - (NSString *)randomNonce:(NSInteger)length {
        NSAssert(length > 0, @"Expected nonce to have positive length");
        NSString *characterSet = @"0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._";
        NSMutableString *result = [NSMutableString string];
        NSInteger remainingLength = length;
    
        while (remainingLength > 0) {
          NSMutableArray *randoms = [NSMutableArray arrayWithCapacity:16];
          for (NSInteger i = 0; i < 16; i++) {
            uint8_t random = 0;
            int errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random);
            NSAssert(errorCode == errSecSuccess, @"Unable to generate nonce: OSStatus %i", errorCode);
    
            [randoms addObject:@(random)];
          }
    
          for (NSNumber *random in randoms) {
            if (remainingLength == 0) {
              break;
            }
    
            if (random.unsignedIntValue < characterSet.length) {
              unichar character = [characterSet characterAtIndex:random.unsignedIntValue];
              [result appendFormat:@"%C", character];
              remainingLength--;
            }
          }
        }
      }
    
    

    Anda akan mengirimkan hash SHA256 nonce bersama permintaan login, yang tidak akan diubah oleh Apple dalam responsnya. Firebase akan memvalidasi respons tersebut dengan melakukan hashing nonce yang asli dan membandingkannya dengan nilai yang diteruskan oleh Apple.

  2. Mulai jalankan alur login Apple, termasuk di permintaan Anda, hash SHA256 nonce dan class delegasi yang akan menangani respons Apple (baca langkah berikutnya):

      - (void)startSignInWithAppleFlow {
        NSString *nonce = [self randomNonce:32];
        self.currentNonce = nonce;
        ASAuthorizationAppleIDProvider *appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init];
        ASAuthorizationAppleIDRequest *request = [appleIDProvider createRequest];
        request.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];
        request.nonce = [self stringBySha256HashingString:nonce];
    
        ASAuthorizationController *authorizationController =
            [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]];
        authorizationController.delegate = self;
        authorizationController.presentationContextProvider = self;
        [authorizationController performRequests];
      }
    
      - (NSString *)stringBySha256HashingString:(NSString *)input {
        const char *string = [input UTF8String];
        unsigned char result[CC_SHA256_DIGEST_LENGTH];
        CC_SHA256(string, (CC_LONG)strlen(string), result);
    
        NSMutableString *hashed = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
        for (NSInteger i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
          [hashed appendFormat:@"%02x", result[i]];
        }
        return hashed;
      }
    
  3. Menangani respons Apple dalam implementasi ASAuthorizationControllerDelegate`. Jika proses login berhasil, gunakan token ID dari respons Apple dengan nonce yang tidak di-hash untuk diautentikasi dengan Firebase:

      - (void)authorizationController:(ASAuthorizationController *)controller
         didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0)) {
        if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
          ASAuthorizationAppleIDCredential *appleIDCredential = authorization.credential;
          NSString *rawNonce = self.currentNonce;
          NSAssert(rawNonce != nil, @"Invalid state: A login callback was received, but no login request was sent.");
    
          if (appleIDCredential.identityToken == nil) {
            NSLog(@"Unable to fetch identity token.");
            return;
          }
    
          NSString *idToken = [[NSString alloc] initWithData:appleIDCredential.identityToken
                                                    encoding:NSUTF8StringEncoding];
          if (idToken == nil) {
            NSLog(@"Unable to serialize id token from data: %@", appleIDCredential.identityToken);
          }
        }
    
  4. Gunakan string token dan nonce asli yang dihasilkan untuk membuat Kredensial Firebase dan login ke Firebase.

    firebase::auth::OAuthProvider::GetCredential(
            /*provider_id=*/"apple.com", token, nonce,
            /*access_token=*/nullptr);
    
    firebase::Future<firebase::auth::User*> result =
        auth->SignInWithCredential(credential);
    
  5. Pola yang sama dapat digunakan dengan Reauthenticate yang dapat digunakan untuk mengambil kredensial baru untuk operasi sensitif yang memerlukan login terbaru.

    firebase::Future<firebase::auth::SignInResult> result =
        user->Reauthenticate(credential);
    
  6. Pola yang sama dapat digunakan untuk menautkan akun dengan Login Apple. Namun, Anda mungkin akan mengalami error saat akun Firebase yang ada telah ditautkan ke akun Apple yang Anda coba tautkan. Jika ini terjadi, Future akan menampilkan status kAuthErrorCredentialAlreadyInUse dan objek UserInfo SignInResult dapat berisi updated_credential yang valid. Kredensial ini dapat digunakan untuk membuat akun yang tertaut dengan Apple login melalui SignInWithCredential tanpa perlu membuat token dan nonce Login Apple.

    Perlu diperhatikan bahwa Anda harus menggunakan LinkAndRetrieveDataWithCredential agar operasi ini berisi kredensial karena updated_credential adalah anggota objek SignInResult.UserInfo.

    firebase::Future<firebase::auth::SignInResult> link_result =
        auth->current_user()->LinkAndRetrieveDataWithCredential(credential);
    
    // To keep example simple, wait on the current thread until call completes.
    while (link_result.status() == firebase::kFutureStatusPending) {
      Wait(100);
    }
    
    // Determine the result of the link attempt
    if (link_result.error() == firebase::auth::kAuthErrorNone) {
      // user linked correctly.
    } else if (link_result.error() ==
                   firebase::auth::kAuthErrorCredentialAlreadyInUse &&
               link_result.result()->info.updated_credential.is_valid()) {
      // Sign In with the new credential
      firebase::Future<firebase::auth::User*> result = auth->SignInWithCredential(
          link_result.result()->info.updated_credential);
    } else {
      // Another link error occurred.
    }
    

Di Android

Pada Android, lakukan autentikasi pengguna dengan Firebase, dengan mengintegrasikan Login OAuth umum berbasis web ke dalam Firebase SDK untuk melakukan alur login menyeluruh.

Untuk menangani alur login dengan Firebase SDK, ikuti langkah-langkah berikut:

  1. Buat instance FederatedOAuthProviderData yang dikonfigurasi dengan ID penyedia yang sesuai untuk Apple.

    firebase::auth::FederatedOAuthProviderData provider_data("apple.com");
    
  2. Opsional: Tentukan cakupan OAuth 2.0 tambahan di luar default yang ingin Anda minta dari penyedia autentikasi.

    provider_data.scopes.push_back("email");
    provider_data.scopes.push_back("name");
    
  3. Opsional: Jika Anda ingin menampilkan layar login Apple dalam bahasa lain selain bahasa Inggris, tetapkan parameter locale. Baca dokumen Login dengan Apple untuk lokal yang didukung.

    // Localize to French.
    provider_data.custom_parameters["language"] = "fr";
    ```
    
  4. Setelah data penyedia Anda dikonfigurasi, gunakan data tersebut untuk membuat FederatedOAuthProvider.

    // Construct a FederatedOAuthProvider for use in Auth methods.
    firebase::auth::FederatedOAuthProvider provider(provider_data);
    
  5. Lakukan autentikasi dengan Firebase menggunakan objek penyedia Auth. Perlu diperhatikan bahwa tidak seperti operasi FirebaseAuth lainnya, tindakan ini akan mengendalikan UI Anda dengan memunculkan tampilan web, tempat pengguna dapat memasukkan kredensial mereka.

    Untuk memulai alur login, panggil signInWithProvider:

    firebase::Future<firebase::auth::SignInResult> result =
      auth->SignInWithProvider(provider_data);
    

    Selanjutnya, aplikasi Anda dapat menunggu atau mendaftarkan callback pada Future.

  6. Pola yang sama dapat digunakan dengan ReauthenticateWithProvider yang dapat digunakan untuk mengambil kredensial baru untuk operasi sensitif yang memerlukan login terbaru.

    firebase::Future<firebase::auth::SignInResult> result =
      user->ReauthenticateWithProvider(provider_data);
    

    Selanjutnya, aplikasi Anda dapat menunggu atau mendaftarkan callback pada Future.

  7. Selain itu, Anda dapat menggunakan linkWithCredential() untuk menautkan penyedia identitas yang berbeda ke akun yang ada.

    Perlu diperhatikan bahwa Apple mewajibkan Anda untuk mendapatkan persetujuan eksplisit dari pengguna sebelum Anda menautkan akun Apple mereka ke data lain.

    Misalnya, untuk menautkan akun Facebook ke akun Firebase saat ini, gunakan token akses yang Anda peroleh saat pengguna login ke Facebook:

    // Initialize a Facebook credential with a Facebook access token.
    AuthCredential credential =
        firebase::auth::FacebookAuthProvider.getCredential(token);
    
    // Assuming the current user is an Apple user linking a Facebook provider.
    firebase::Future<firebase::auth::SignInResult> result =
        auth.getCurrentUser().linkWithCredential(credential);
    

Login dengan Apple Notes

Tidak seperti penyedia lain yang didukung oleh Firebase Auth, Apple tidak memberikan URL foto.

Selain itu, jika pengguna memilih untuk tidak berbagi email dengan aplikasi, Apple akan menyediakan alamat email unik untuk pengguna tersebut (dari formulir xyz@privaterelay.appleid.com), yang dibagikan dengan aplikasi Anda. Jika Anda mengonfigurasi layanan relai email pribadi, Apple akan meneruskan email yang dikirim ke alamat anonim ke alamat email asli pengguna.

Apple hanya membagikan informasi pengguna seperti nama tampilan dengan aplikasi saat pengguna login untuk pertama kalinya. Biasanya, Firebase menyimpan nama yang ditampilkan saat pengguna login dengan Apple untuk pertama kalinya, yang dapat Anda peroleh dengan getCurrentUser().getDisplayName(). Namun, jika sebelumnya Anda menggunakan Apple untuk membuat pengguna login ke aplikasi tanpa menggunakan Firebase, Apple tidak akan memberikan nama yang ditampilkan kepada Firebase.

Langkah berikutnya

Setelah pengguna login untuk pertama kalinya, akun pengguna baru akan dibuat dan ditautkan ke kredensial, yaitu nama pengguna dan sandi, nomor telepon, atau informasi penyedia autentikasi, yang digunakan pengguna tersebut untuk login. Akun baru ini disimpan sebagai bagian dari project Firebase Anda, dan dapat digunakan untuk mengidentifikasi pengguna di setiap aplikasi dalam project, terlepas dari cara pengguna login.

Di aplikasi, Anda bisa mendapatkan informasi profil dasar pengguna dari objek firebase::auth::user object. Lihat Mengelola Pengguna.

Di Aturan Keamanan Firebase Realtime Database dan Cloud Storage, Anda bisa mendapatkan ID pengguna unik yang login dari variabel autentikasi, dan menggunakannya untuk mengontrol data yang dapat diakses oleh pengguna.