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

Otentikasi Menggunakan Apple dan C++

Anda dapat mengizinkan pengguna melakukan autentikasi dengan Firebase menggunakan ID Apple mereka dengan menggunakan SDK Firebase untuk menjalankan alur masuk OAuth 2.0 menyeluruh.

Sebelum kamu memulai

Untuk masuk ke pengguna menggunakan Apple, pertama-tama konfigurasikan Masuk dengan Apple di situs pengembang Apple, lalu aktifkan Apple sebagai penyedia masuk untuk proyek Firebase Anda.

Bergabunglah dengan Program Pengembang Apple

Masuk dengan Apple hanya dapat dikonfigurasi oleh anggota Program Pengembang Apple .

Konfigurasi Masuk dengan Apple

Masuk dengan Apple harus diaktifkan dan dikonfigurasi dengan benar di proyek Firebase Anda. Konfigurasi bervariasi di seluruh platform Android dan Apple. Harap ikuti bagian "Konfigurasikan Masuk Dengan Apple" pada platform Apple dan/atau panduan Android sebelum melanjutkan.

Aktifkan Apple sebagai penyedia masuk

  1. Di Firebase console , buka bagian Auth . Pada tab Metode masuk , aktifkan penyedia Apple .
  2. Konfigurasikan pengaturan penyedia Masuk Apple:
    1. Jika Anda menerapkan aplikasi hanya pada platform Apple, Anda dapat mengosongkan bidang ID Layanan, ID Tim Apple, kunci pribadi, dan ID kunci.
    2. Untuk dukungan pada perangkat Android:
      1. Tambahkan Firebase ke proyek Android Anda . Pastikan untuk mendaftarkan tanda tangan SHA-1 aplikasi Anda saat menyiapkan aplikasi di Firebase console.
      2. Di Firebase console , buka bagian Auth . Pada tab Metode masuk , aktifkan penyedia Apple . Tentukan ID Layanan yang Anda buat di bagian sebelumnya. Selain itu, di bagian konfigurasi alur kode OAuth, tentukan ID Tim Apple Anda serta kunci pribadi dan ID kunci yang Anda buat di bagian sebelumnya.

Patuhi persyaratan data anonim Apple

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

Ini termasuk memperoleh persetujuan pengguna yang diperlukan sebelum Anda mengaitkan informasi pribadi apa pun yang mengidentifikasi secara langsung dengan ID Apple yang dianonimkan. Saat menggunakan Firebase Authentication, tindakan ini dapat mencakup tindakan berikut:

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

Daftar di atas tidak lengkap. Lihat Perjanjian Lisensi Program Pengembang Apple di bagian Keanggotaan akun pengembang Anda untuk memastikan aplikasi Anda memenuhi persyaratan Apple.

Akses firebase::auth::Auth class

Kelas Auth adalah gerbang untuk semua panggilan API.
  1. Tambahkan file header Auth dan Aplikasi:
    #include "firebase/app.h"
    #include "firebase/auth.h"
    
  2. Dalam kode inisialisasi Anda, buat kelas 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 kelas firebase::auth::Auth untuk firebase::App Anda. Ada pemetaan satu-ke-satu antara App dan Auth .
    firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);
    

Tangani alur masuk dengan Firebase SDK

Proses untuk Masuk Dengan Apple bervariasi di seluruh platform Apple dan Android.

Di platform Apple

Otentikasi pengguna Anda dengan Firebase melalui Apple Sign In Objective-C SDK yang dipanggil dari kode C++ Anda.

  1. Untuk setiap permintaan masuk, buat string acak—"nonce"—yang akan Anda gunakan untuk memastikan token ID yang Anda dapatkan diberikan secara khusus sebagai tanggapan atas permintaan autentikasi aplikasi Anda. Langkah ini penting untuk mencegah 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 dari nonce dengan permintaan masuk Anda, yang akan diteruskan oleh Apple tanpa perubahan dalam tanggapannya. Firebase memvalidasi respons dengan hashing nonce asli dan membandingkannya dengan nilai yang diteruskan oleh Apple.

  2. Mulai alur masuk Apple, termasuk dalam permintaan Anda hash SHA256 dari nonce dan kelas delegasi yang akan menangani respons Apple (lihat 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. Tangani respons Apple dalam implementasi ASAuthorizationControllerDelegate` Anda. Jika proses masuk berhasil, gunakan token ID dari respons Apple dengan nonce tanpa hash untuk mengautentikasi 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 yang dihasilkan dan nonce asli untuk membuat Kredensial Firebase dan masuk 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 baru-baru ini.

    firebase::Future<firebase::auth::SignInResult> result =
        user->Reauthenticate(credential);
    
  6. Pola yang sama dapat digunakan untuk menautkan akun dengan Apple Sign In. Namun, Anda mungkin mengalami kesalahan saat akun Firebase yang ada telah ditautkan ke akun Apple yang Anda coba tautkan. Ketika ini terjadi, masa depan akan mengembalikan status kAuthErrorCredentialAlreadyInUse dan objek UserInfo dari SignInResult mungkin berisi updated_credential yang valid. Kredensial ini dapat digunakan untuk masuk ke akun tertaut Apple melalui SignInWithCredential tanpa perlu membuat token dan nonce Masuk Apple lainnya.

    Perhatikan bahwa Anda harus menggunakan LinkAndRetrieveDataWithCredential agar operasi ini memuat 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

Di Android, autentikasi pengguna Anda dengan Firebase dengan mengintegrasikan OAuth Login generik berbasis web ke dalam aplikasi Anda menggunakan Firebase SDK untuk menjalankan alur masuk menyeluruh.

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

  1. Buat instance dari 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 masuk Apple dalam bahasa selain bahasa Inggris, atur parameter locale . Lihat dokumen Masuk dengan Apple untuk lokal yang didukung.

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

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

    Untuk memulai alur masuk, panggil signInWithProvider :

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

    Aplikasi Anda kemudian dapat menunggu atau mendaftarkan panggilan balik di Masa Depan .

  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);
    

    Aplikasi Anda kemudian dapat menunggu atau mendaftarkan panggilan balik di Masa Depan .

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

    Perhatikan bahwa Apple mengharuskan 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 dapatkan dari memasukkan pengguna 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);
    

Masuk dengan Apple Notes

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

Selain itu, saat pengguna memilih untuk tidak membagikan email mereka dengan aplikasi, Apple menyediakan alamat email unik untuk pengguna tersebut (dalam bentuk xyz@privaterelay.appleid.com ), yang dibagikan dengan aplikasi Anda. Jika Anda mengonfigurasi layanan relai email pribadi, Apple meneruskan email yang dikirim ke alamat anonim ke alamat email asli pengguna.

Apple hanya membagikan informasi pengguna seperti nama tampilan dengan aplikasi saat pertama kali pengguna masuk. Biasanya, Firebase menyimpan nama tampilan saat pertama kali pengguna masuk dengan Apple, yang bisa Anda dapatkan dengan getCurrentUser().getDisplayName() . Namun, jika sebelumnya Anda menggunakan Apple untuk memasukkan pengguna ke aplikasi tanpa menggunakan Firebase, Apple tidak akan memberikan nama tampilan pengguna kepada Firebase.

Langkah selanjutnya

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

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

Dalam Aturan Keamanan Firebase Realtime Database dan Cloud Storage, Anda bisa mendapatkan ID pengguna unik pengguna yang masuk dari variabel auth, dan menggunakannya untuk mengontrol data apa yang dapat diakses pengguna.