Apple ve C++ Kullanarak Kimlik Doğrula

Uçtan uca OAuth 2.0 oturum açma akışını gerçekleştirmek için Firebase SDK'sını kullanarak kullanıcılarınızın Apple Kimliklerini kullanarak Firebase'de kimlik doğrulaması yapmasına izin verebilirsiniz.

Başlamadan önce

Kullanıcıların Apple ile oturum açmasını sağlamak için önce Apple'ın geliştirici sitesinde Apple ile Oturum Açma'yı yapılandırın, ardından Firebase projeniz için oturum açma sağlayıcı olarak Apple'ı etkinleştirin.

Apple Geliştirici Programı'na katılma

Apple ile oturum açma özelliği yalnızca Apple Developer Program üyeleri tarafından yapılandırılabilir.

Apple ile oturum açma özelliğini yapılandırma

Firebase projenizde Apple ile Giriş etkinleştirilmeli ve doğru şekilde yapılandırılmalıdır. Yapılandırma, Android ve Apple platformlarında farklılık gösterir. Lütfen devam etmeden önce Apple platformları ve/veya Android kılavuzlarının "Apple ile Giriş Yap'ı yapılandırma" bölümündeki adımları uygulayın.

Apple'ı oturum açma sağlayıcısı olarak etkinleştirme

  1. Firebase konsolunda Auth (Kimlik Doğrulama) bölümünü açın. Oturum açma yöntemi sekmesinde Apple sağlayıcısını etkinleştirin.
  2. Apple ile oturum açma sağlayıcı ayarlarını yapılandırın:
    1. Uygulamanızı yalnızca Apple platformlarında dağıtıyorsanız Hizmet Kimliği, Apple Ekip Kimliği, özel anahtar ve anahtar kimliği alanlarını boş bırakabilirsiniz.
    2. Android cihazlarda destek için:
      1. Firebase'i Android projenize ekleyin. Uygulamanızı Firebase konsolunda ayarlarken uygulamanızın SHA-1 imzasını kaydettiğinizden emin olun.
      2. Firebase konsolunda Auth bölümünü açın. Oturum açma yöntemi sekmesinde Apple sağlayıcısını etkinleştirin. Önceki bölümde oluşturduğunuz hizmet kimliğini belirtin. Ayrıca, OAuth kod akışı yapılandırması bölümünde Apple Ekip Kimliğinizi ve önceki bölümde oluşturduğunuz özel anahtarı ve anahtar kimliğini belirtin.

Apple'ın anonimleştirilmiş veri şartlarına uyun

Apple ile Giriş, kullanıcılara oturum açarken e-posta adresleri de dahil olmak üzere verilerini anonimleştirme seçeneği sunar. Bu seçeneği belirleyen kullanıcıların privaterelay.appleid.com alan adıyla e-posta adresleri olur. Uygulamanızda Apple ile Giriş'i kullandığınızda, bu anonimleştirilmiş Apple kimlikleriyle ilgili olarak Apple'ın geçerli tüm geliştirici politikalarına veya şartlarına uymanız gerekir.

Bu, kimliği doğrudan tanımlayan kişisel bilgileri anonimleştirilmiş bir Apple Kimliği ile ilişkilendirmeden önce gerekli kullanıcı iznini almayı içerir. Firebase Authentication kullanılırken aşağıdaki işlemler yapılabilir:

  • Anonimleştirilmiş bir Apple Kimliği'ne e-posta adresi bağlayabilir veya tam tersini yapabilirsiniz.
  • Anonimleştirilmiş bir Apple Kimliği'ne telefon numarası bağlama veya tam tersi
  • Anonim olmayan bir sosyal kimlik bilgisini (Facebook, Google vb.) anonimleştirilmiş bir Apple Kimliği'ne veya tam tersi şekilde bağlamak

Yukarıdaki listede olası her duruma yer verilmemiştir. Uygulamanızın Apple'ın şartlarını karşıladığından emin olmak için geliştirici hesabınızın Üyelik bölümündeki Apple Geliştirici Programı Lisans Sözleşmesi'ne bakın.

firebase::auth::Auth sınıfına erişme

Auth sınıfı, tüm API çağrıları için ağ geçididir.
  1. Auth ve App üstbilgi dosyalarını ekleyin:
    #include "firebase/app.h"
    #include "firebase/auth.h"
  2. Başlatma kodunuzda bir firebase::App sınıfı oluşturun.
    #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. firebase::auth::Auth sınıfını firebase::App için edinin. App ile Auth arasında bire bir eşleme vardır.
    firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);

Firebase SDK ile oturum açma akışını yönetme

Apple ile oturum açma işlemi, Apple ve Android platformlarında farklılık gösterir.

Apple platformlarında

C++ kodunuzdan çağrılan Apple ile Giriş Objective-C SDK'sı aracılığıyla kullanıcılarınızın kimliğini Firebase ile doğrulayın.

  1. Her oturum açma isteği için rastgele bir dize ("nonce") oluşturun. Bu dizeyi, aldığınız kimlik jetonunun özellikle uygulamanızın kimlik doğrulama isteğine yanıt olarak verildiğinden emin olmak için kullanırsınız. Bu adım, yeniden oynatma saldırılarını önlemek için önemlidir.

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

    Oturum açma isteğinizle birlikte nonce'ın SHA256 hash değerini gönderirsiniz. Bu değer, Apple tarafından yanıtta değiştirilmeden iletilir. Firebase, orijinal nonce'ı karma oluşturma işlevinden geçirerek ve Apple tarafından iletilen değerle karşılaştırarak yanıtı doğrular.

  2. İsteğinize, Apple'ın yanıtını işleyecek olan nonce'ın ve temsilci sınıfının SHA256 karmasını da ekleyerek Apple'ın oturum açma akışını başlatın (sonraki adıma bakın):

      - (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. Apple'ın yanıtını <code>ASAuthorizationControllerDelegate</code> uygulamanızda işleyin. Oturum açma işlemi başarılı olduysa Firebase ile kimlik doğrulamak için Apple'ın yanıtındaki ID jetonunu karma oluşturulmamış nonce ile birlikte kullanın:

      - (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. FirebaseCredential oluşturmak ve Firebase'de oturum açmak için sonuçta elde edilen jeton dizesini ve orijinal nonce'ı kullanın.

    firebase::auth::OAuthProvider::GetCredential(
            /*provider_id=*/"apple.com", token, nonce,
            /*access_token=*/nullptr);
    
    firebase::Future<firebase::auth::AuthResult> result =
        auth->SignInAndRetrieveDataWithCredential(credential);
    
  5. Aynı kalıp, son giriş gerektiren hassas işlemler için yeni kimlik bilgilerini almak üzere kullanılabilen Reauthenticate ile de kullanılabilir.

    firebase::Future<firebase::auth::AuthResult> result =
        user->Reauthenticate(credential);
    
  6. Hesabı Apple ile Giriş'e bağlamak için de aynı yöntem kullanılabilir. Ancak, mevcut bir Firebase hesabı, bağlamaya çalıştığınız Apple hesabına zaten bağlıysa bir hatayla karşılaşabilirsiniz. Bu durumda gelecekteki durum kAuthErrorCredentialAlreadyInUse olarak döndürülür ve AuthResult geçerli bir credential içerebilir. Bu kimlik bilgisi, başka bir Apple ile oturum açma jetonu ve nonce oluşturmaya gerek kalmadan SignInAndRetrieveDataWithCredential üzerinden Apple'a bağlı hesapta oturum açmak için kullanılabilir.

    firebase::Future<firebase::auth::AuthResult> link_result =
        auth->current_user().LinkWithCredential(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()
                   ->additional_user_info.updated_credential.is_valid()) {
      // Sign In with the new credential
      firebase::Future<firebase::auth::AuthResult> result =
          auth->SignInAndRetrieveDataWithCredential(
              link_result.result()->additional_user_info.updated_credential);
    } else {
      // Another link error occurred.
    }

Android'de

Android'de, uçtan uca oturum açma akışını gerçekleştirmek için Firebase SDK'yı kullanarak web tabanlı genel OAuth oturum açma özelliğini uygulamanıza entegre ederek kullanıcılarınızın kimliğini Firebase ile doğrulayın.

Oturum açma akışını Firebase SDK ile işlemek için aşağıdaki adımları uygulayın:

  1. Apple için uygun sağlayıcı kimliğiyle yapılandırılmış bir FederatedOAuthProviderData örneği oluşturun.

    firebase::auth::FederatedOAuthProviderData provider_data("apple.com");
    
  2. İsteğe bağlı: Kimlik doğrulama sağlayıcısından istemek istediğiniz varsayılan kapsamların dışında ek OAuth 2.0 kapsamları belirtin.

    provider_data.scopes.push_back("email");
    provider_data.scopes.push_back("name");
    
  3. İsteğe bağlı: Apple'ın oturum açma ekranını İngilizce dışında bir dilde göstermek istiyorsanız locale parametresini ayarlayın. Desteklenen yerel ayarlar için Apple ile Giriş dokümanlarına bakın.

    // Localize to French.
    provider_data.custom_parameters["language"] = "fr";
    ```
    
  4. Sağlayıcı verileriniz yapılandırıldıktan sonra bu verileri kullanarak FederatedOAuthProvider oluşturun.

    // Construct a FederatedOAuthProvider for use in Auth methods.
    firebase::auth::FederatedOAuthProvider provider(provider_data);
    
  5. Auth sağlayıcı nesnesini kullanarak Firebase ile kimlik doğrulama. Diğer FirebaseAuth işlemlerinden farklı olarak bu işlemin, kullanıcının kimlik bilgilerini girebileceği bir web görünümü açarak kullanıcı arayüzünüzün kontrolünü ele geçireceğini unutmayın.

    Oturum açma akışını başlatmak için signInWithProvider işlevini çağırın:

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

    Başvurunuz bekletilebilir veya gelecekte geri arama kaydı oluşturulabilir.

  6. Aynı kalıp, son giriş gerektiren hassas işlemler için yeni kimlik bilgilerini almak üzere kullanılabilen ReauthenticateWithProvider ile de kullanılabilir.

    firebase::Future<firebase::auth::AuthResult> result =
      user.ReauthenticateWithProvider(provider_data);
    

    Uygulamanız daha sonra bekleyebilir veya Future'da geri arama kaydı oluşturabilir.

  7. Ayrıca, farklı kimlik sağlayıcıları mevcut hesaplara bağlamak için LinkWithCredential() simgesini kullanabilirsiniz.

    Apple'ın, kullanıcıların Apple hesaplarını diğer verilere bağlamadan önce kullanıcılardan açık rıza almanızı zorunlu kıldığını unutmayın.

    Örneğin, bir Facebook hesabını mevcut Firebase hesabına bağlamak için kullanıcının Facebook'ta oturum açmasıyla aldığınız erişim jetonunu kullanın:

    // 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::AuthResult> result =
        auth.current_user().LinkWithCredential(credential);
    

Apple Notlar ile oturum açma

Firebase Auth tarafından desteklenen diğer sağlayıcıların aksine Apple, fotoğraf URL'si sağlamaz.

Ayrıca, kullanıcı e-postasını uygulamayla paylaşmamayı seçtiğinde Apple, bu kullanıcı için benzersiz bir e-posta adresi (xyz@privaterelay.appleid.com biçiminde) sağlar ve bu adresi uygulamanızla paylaşır. Özel e-posta geçiş hizmetini yapılandırdıysanız Apple, anonimleştirilmiş adrese gönderilen e-postaları kullanıcının gerçek e-posta adresine yönlendirir.

Apple, kullanıcı bilgilerini (ör. görünen ad) uygulamalarla yalnızca kullanıcı ilk kez oturum açtığında paylaşır. Firebase, genellikle kullanıcının Apple ile ilk kez oturum açtığında görünen adı depolar. Bu adı current_user().display_name() ile alabilirsiniz. Ancak daha önce Firebase'i kullanmadan bir kullanıcının uygulamada oturum açması için Apple'ı kullandıysanız Apple, Firebase'e kullanıcının görünen adını sağlamaz.

Sonraki adımlar

Kullanıcı ilk kez oturum açtıktan sonra yeni bir kullanıcı hesabı oluşturulur ve kullanıcının oturum açtığı kimlik bilgilerine (kullanıcı adı ve şifre, telefon numarası veya kimlik doğrulama sağlayıcı bilgileri) bağlanır. Bu yeni hesap, Firebase projenizin bir parçası olarak depolanır ve kullanıcının oturum açma şeklinden bağımsız olarak projenizdeki her uygulamada kullanıcıyı tanımlamak için kullanılabilir.

Uygulamalarınızda, kullanıcının temel profil bilgilerini firebase::auth::User nesnesinden alabilirsiniz. Kullanıcıları yönetme başlıklı makaleyi inceleyin.

Firebase Realtime Database ve Cloud Storage güvenlik kurallarınızda, kimlik doğrulama değişkeninden oturum açmış kullanıcının benzersiz kullanıcı kimliğini alabilir ve bunu, kullanıcının hangi verilere erişebileceğini kontrol etmek için kullanabilirsiniz.