Join us in person and online for Firebase Summit on October 18, 2022. Learn how Firebase can help you accelerate app development, release your app with confidence, and scale with ease. Register now

Uwierzytelnij się za pomocą Apple na Androidzie

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.

Możesz zezwolić użytkownikom na uwierzytelnianie w Firebase przy użyciu ich Apple ID, używając pakietu Firebase SDK do przeprowadzania kompleksowego procesu logowania OAuth 2.0.

Zanim zaczniesz

Aby logować użytkowników za pomocą Apple, najpierw skonfiguruj Zaloguj się za pomocą Apple w witrynie programisty Apple, a następnie włącz Apple jako dostawcę logowania do projektu Firebase.

Dołącz do programu Apple Developer

Funkcja logowania za pomocą Apple może być konfigurowana tylko przez członków programu Apple Developer Program .

Skonfiguruj Zaloguj się za pomocą Apple

W witrynie Apple Developer wykonaj następujące czynności:

  1. Powiąż swoją witrynę internetową z aplikacją zgodnie z opisem w pierwszej sekcji Konfiguruj logowanie za pomocą Apple dla sieci Web . Po wyświetleniu monitu zarejestruj następujący adres URL jako zwrotny adres URL:

    https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler

    Identyfikator projektu Firebase możesz uzyskać na stronie ustawień konsoli Firebase .

    Po zakończeniu zanotuj swój nowy identyfikator usługi, który będzie Ci potrzebny w następnej sekcji.

  2. Utwórz Zaloguj się przy użyciu klucza prywatnego Apple . W następnej sekcji będziesz potrzebować nowego klucza prywatnego i identyfikatora klucza.
  3. Jeśli korzystasz z dowolnej funkcji uwierzytelniania Firebase, która umożliwia wysyłanie wiadomości e-mail do użytkowników, w tym logowania się za pomocą łącza do poczty e-mail, weryfikacji adresu e-mail, cofnięcia zmiany konta i innych, skonfiguruj usługę przekazywania prywatnych wiadomości e-mail Apple i zarejestruj noreply@ YOUR_FIREBASE_PROJECT_ID .firebaseapp.com (lub dostosowanej domeny szablonu wiadomości e-mail), dzięki czemu Apple może przekazywać wiadomości e-mail wysyłane przez uwierzytelnianie Firebase na anonimowe adresy e-mail Apple.

Włącz Apple jako dostawcę logowania

  1. Dodaj Firebase do swojego projektu na Androida . Pamiętaj, aby zarejestrować podpis SHA-1 swojej aplikacji podczas konfigurowania aplikacji w konsoli Firebase.
  2. W konsoli Firebase otwórz sekcję Auth . Na karcie Metoda logowania włącz dostawcę Apple . Podaj identyfikator usługi utworzony w poprzedniej sekcji. Ponadto w sekcji konfiguracji przepływu kodu OAuth określ identyfikator zespołu Apple oraz klucz prywatny i identyfikator klucza utworzony w poprzedniej sekcji.

Przestrzegaj wymagań Apple dotyczących anonimowych danych

Zaloguj się za pomocą Apple daje użytkownikom możliwość anonimizacji swoich danych, w tym adresu e-mail, podczas logowania. Użytkownicy, którzy wybiorą tę opcję, mają adresy e-mail z domeną privaterelay.appleid.com . Korzystając z funkcji Zaloguj się przez Apple w swojej aplikacji, musisz przestrzegać wszelkich obowiązujących zasad lub warunków dla programistów Apple dotyczących tych anonimowych identyfikatorów Apple ID.

Obejmuje to uzyskanie wymaganej zgody użytkownika przed powiązaniem jakichkolwiek bezpośrednio identyfikujących danych osobowych z anonimowym identyfikatorem Apple ID. Podczas korzystania z Uwierzytelniania Firebase może to obejmować następujące działania:

  • Połącz adres e-mail z anonimowym identyfikatorem Apple ID lub odwrotnie.
  • Połącz numer telefonu z anonimowym identyfikatorem Apple ID lub odwrotnie
  • Połącz nieanonimowe dane logowania społecznościowego (Facebook, Google itp.) z anonimowym identyfikatorem Apple ID lub odwrotnie.

Powyższa lista nie jest wyczerpująca. Zapoznaj się z Umową licencyjną programu Apple Developer w sekcji Członkostwo swojego konta programisty, aby upewnić się, że Twoja aplikacja spełnia wymagania Apple.

Obsługuj proces logowania za pomocą pakietu Firebase SDK

W systemie Android najłatwiejszym sposobem uwierzytelnienia użytkowników w Firebase przy użyciu ich kont Apple jest obsługa całego procesu logowania za pomocą pakietu Firebase Android SDK.

Aby obsłużyć proces logowania za pomocą pakietu Firebase Android SDK, wykonaj następujące czynności:

  1. Skonstruuj wystąpienie OAuthProvider przy użyciu jego Konstruktora z identyfikatorem dostawcy apple.com :

    Java

    OAuthProvider.Builder provider = OAuthProvider.newBuilder("apple.com");
    

    Kotlin+KTX

    val provider = OAuthProvider.newBuilder("apple.com")
    
  2. Opcjonalnie: określ dodatkowe zakresy OAuth 2,0 poza zakresem domyślnym, którego chcesz zażądać od dostawcy uwierzytelniania.

    Java

    List<String> scopes =
        new ArrayList<String>() {
          {
            add("email");
            add("name");
          }
        };
    provider.setScopes(scopes);
    

    Kotlin+KTX

    provider.setScopes(arrayOf("email", "name"))
    

    Domyślnie, gdy jedno konto na adres e-mail jest włączone, Firebase żąda zakresów adresów e-mail i nazw. Jeśli zmienisz to ustawienie na Wiele kont na adres e-mail , Firebase nie zażąda żadnych zakresów od Apple, chyba że je określisz.

  3. Opcjonalnie: jeśli chcesz wyświetlić ekran logowania Apple w języku innym niż angielski, ustaw parametr locale . Obsługiwane języki można znaleźć w dokumencie Zaloguj się za pomocą Apple .

    Java

    // Localize the Apple authentication screen in French.
    provider.addCustomParameter("locale", "fr");
    

    Kotlin+KTX

    // Localize the Apple authentication screen in French.
    provider.addCustomParameter("locale", "fr")
    
  4. Uwierzytelnij się w Firebase przy użyciu obiektu dostawcy OAuth. Pamiętaj, że w przeciwieństwie do innych operacji FirebaseAuth ta funkcja przejmie kontrolę nad Twoim interfejsem użytkownika po otwarciu niestandardowej karty Chrome. W związku z tym nie odwołuj się do działania w OnSuccessListener i OnFailureListener , które dołączasz, ponieważ zostaną one natychmiast odłączone, gdy operacja uruchomi interfejs użytkownika.

    Powinieneś najpierw sprawdzić, czy otrzymałeś już odpowiedź. Zalogowanie się tą metodą umieszcza Twoją Aktywność w tle, co oznacza, że ​​może zostać odzyskana przez system podczas procesu logowania. Aby mieć pewność, że nie zmusisz użytkownika do ponownej próby, jeśli tak się stanie, powinieneś sprawdzić, czy wynik jest już obecny.

    Aby sprawdzić, czy istnieje oczekujący wynik, wywołaj getPendingAuthResult() :

    Java

    mAuth = FirebaseAuth.getInstance();
    Task<AuthResult> pending = mAuth.getPendingAuthResult();
    if (pending != null) {
        pending.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
            @Override
            public void onSuccess(AuthResult authResult) {
                Log.d(TAG, "checkPending:onSuccess:" + authResult);
                // Get the user profile with authResult.getUser() and
                // authResult.getAdditionalUserInfo(), and the ID
                // token from Apple with authResult.getCredential().
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.w(TAG, "checkPending:onFailure", e);
            }
        });
    } else {
        Log.d(TAG, "pending: null");
    }
    

    Kotlin+KTX

    val pending = auth.pendingAuthResult
    if (pending != null) {
        pending.addOnSuccessListener { authResult ->
            Log.d(TAG, "checkPending:onSuccess:$authResult")
            // Get the user profile with authResult.getUser() and
            // authResult.getAdditionalUserInfo(), and the ID
            // token from Apple with authResult.getCredential().
        }.addOnFailureListener { e ->
            Log.w(TAG, "checkPending:onFailure", e)
        }
    } else {
        Log.d(TAG, "pending: null")
    }
    

    Jeśli nie ma oczekującego wyniku, rozpocznij przepływ logowania, wywołując startActivityForSignInWithProvider() :

    Java

    mAuth.startActivityForSignInWithProvider(this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // Sign-in successful!
                            Log.d(TAG, "activitySignIn:onSuccess:" + authResult.getUser());
                            FirebaseUser user = authResult.getUser();
                            // ...
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            Log.w(TAG, "activitySignIn:onFailure", e);
                        }
                    });
    

    Kotlin+KTX

    auth.startActivityForSignInWithProvider(this, provider.build())
            .addOnSuccessListener { authResult ->
                // Sign-in successful!
                Log.d(TAG, "activitySignIn:onSuccess:${authResult.user}")
                val user = authResult.user
                // ...
            }
            .addOnFailureListener { e ->
                Log.w(TAG, "activitySignIn:onFailure", e)
            }
    

    W przeciwieństwie do innych dostawców obsługiwanych przez Firebase Auth, Apple nie udostępnia adresu URL zdjęcia.

    Ponadto, gdy użytkownik zdecyduje się nie udostępniać swojego adresu e-mail aplikacji, Apple przydziela mu unikalny adres e-mail (w postaci xyz@privaterelay.appleid.com ), który udostępnia Twojej aplikacji. Jeśli skonfigurowałeś usługę przekazywania prywatnych wiadomości e-mail, Apple przekazuje wiadomości e-mail wysyłane na anonimowy adres na prawdziwy adres e-mail użytkownika.

    Firma Apple udostępnia aplikacjom informacje o użytkowniku, takie jak nazwa wyświetlana, tylko przy pierwszym logowaniu użytkownika. Zazwyczaj Firebase przechowuje nazwę wyświetlaną, gdy użytkownik loguje się do Apple po raz pierwszy, co można uzyskać za pomocą getCurrentUser().getDisplayName() . Jeśli jednak wcześniej logowałeś użytkownika do aplikacji za pomocą Apple bez użycia Firebase, Apple nie udostępni Firebase nazwy wyświetlanej użytkownika.

Ponowne uwierzytelnianie i łączenie kont

Ten sam wzorzec może być użyty z startActivityForReauthenticateWithProvider() , której można użyć do pobrania nowego poświadczenia dla poufnych operacji, które wymagają niedawnego logowania:

Java

// The user is already signed-in.
FirebaseUser firebaseUser = mAuth.getCurrentUser();

firebaseUser
    .startActivityForReauthenticateWithProvider(/* activity= */ this, provider.build())
    .addOnSuccessListener(
        new OnSuccessListener<AuthResult>() {
          @Override
          public void onSuccess(AuthResult authResult) {
            // User is re-authenticated with fresh tokens and
            // should be able to perform sensitive operations
            // like account deletion and email or password
            // update.
          }
        })
    .addOnFailureListener(
        new OnFailureListener() {
          @Override
          public void onFailure(@NonNull Exception e) {
            // Handle failure.
          }
        });

Kotlin+KTX

// The user is already signed-in.
val firebaseUser = auth.getCurrentUser()

firebaseUser
    .startActivityForReauthenticateWithProvider(/* activity= */ this, provider.build())
    .addOnSuccessListener( authResult -> {
        // User is re-authenticated with fresh tokens and
        // should be able to perform sensitive operations
        // like account deletion and email or password
        // update.
    })
    .addOnFailureListener( e -> {
        // Handle failure.
    })

Możesz też użyć linkWithCredential() , aby połączyć różnych dostawców tożsamości z istniejącymi kontami.

Pamiętaj, że Apple wymaga uzyskania wyraźnej zgody użytkowników przed połączeniem ich kont Apple z innymi danymi.

Na przykład, aby połączyć konto Facebook z bieżącym kontem Firebase, użyj tokena dostępu, który otrzymałeś po zalogowaniu użytkownika do Facebooka:

Java

// Initialize a Facebook credential with a Facebook access token.
AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());

// Assuming the current user is an Apple user linking a Facebook provider.
mAuth.getCurrentUser().linkWithCredential(credential)
    .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
      @Override
      public void onComplete(@NonNull Task<AuthResult> task) {
        if (task.isSuccessful()) {
          // Facebook credential is linked to the current Apple user.
          // The user can now sign in to the same account
          // with either Apple or Facebook.
        }
      }
    });

Kotlin+KTX

// Initialize a Facebook credential with a Facebook access token.
val credential = FacebookAuthProvider.getCredential(token.getToken())

// Assuming the current user is an Apple user linking a Facebook provider.
mAuth.getCurrentUser().linkWithCredential(credential)
    .addOnCompleteListener(this, task -> {
        if (task.isSuccessful()) {
          // Facebook credential is linked to the current Apple user.
          // The user can now sign in to the same account
          // with either Apple or Facebook.
        }
      });

Zaawansowane: Ręczna obsługa procesu logowania

Możesz również uwierzytelnić się w Firebase przy użyciu konta Apple, obsługując proces logowania przy użyciu pakietu Apple Sign-In JS SDK, ręcznie tworząc przepływ OAuth lub korzystając z biblioteki OAuth, takiej jak AppAuth .

  1. Dla każdego żądania logowania wygeneruj losowy ciąg — „nonce” — którego użyjesz, aby upewnić się, że otrzymany token identyfikatora został przyznany w odpowiedzi na żądanie uwierzytelnienia aplikacji. Ten krok jest ważny, aby zapobiec atakom typu powtórka.

    Możesz wygenerować kryptograficznie bezpieczny numer jednorazowy w systemie Android za pomocą SecureRandom , jak w poniższym przykładzie:

    Java

    private String generateNonce(int length) {
        SecureRandom generator = new SecureRandom();
    
        CharsetDecoder charsetDecoder = StandardCharsets.US_ASCII.newDecoder();
        charsetDecoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
        charsetDecoder.onMalformedInput(CodingErrorAction.IGNORE);
    
        byte[] bytes = new byte[length];
        ByteBuffer inBuffer = ByteBuffer.wrap(bytes);
        CharBuffer outBuffer = CharBuffer.allocate(length);
        while (outBuffer.hasRemaining()) {
            generator.nextBytes(bytes);
            inBuffer.rewind();
            charsetDecoder.reset();
            charsetDecoder.decode(inBuffer, outBuffer, false);
        }
        outBuffer.flip();
        return outBuffer.toString();
    }
    

    Kotlin+KTX

    private fun generateNonce(length: Int): String {
        val generator = SecureRandom()
    
        val charsetDecoder = StandardCharsets.US_ASCII.newDecoder()
        charsetDecoder.onUnmappableCharacter(CodingErrorAction.IGNORE)
        charsetDecoder.onMalformedInput(CodingErrorAction.IGNORE)
    
        val bytes = ByteArray(length)
        val inBuffer = ByteBuffer.wrap(bytes)
        val outBuffer = CharBuffer.allocate(length)
        while (outBuffer.hasRemaining()) {
            generator.nextBytes(bytes)
            inBuffer.rewind()
            charsetDecoder.reset()
            charsetDecoder.decode(inBuffer, outBuffer, false)
        }
        outBuffer.flip()
        return outBuffer.toString()
    }
    

    Następnie uzyskaj skrót SHA246 liczby jednorazowej jako ciąg szesnastkowy:

    Java

    private String sha256(String s) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] digest = md.digest(s.getBytes());
        StringBuilder hash = new StringBuilder();
        for (byte c: digest) {
            hash.append(String.format("%02x", c));
        }
        return hash.toString();
    }
    

    Kotlin+KTX

    private fun sha256(s: String): String {
        val md = MessageDigest.getInstance("SHA-256")
        val digest = md.digest(s.toByteArray())
        val hash = StringBuilder()
        for (c in digest) {
            hash.append(String.format("%02x", c))
        }
        return hash.toString()
    }
    

    Wraz z żądaniem logowania wyślesz jednorazowy skrót SHA256, który Apple przekaże bez zmian w odpowiedzi. Firebase weryfikuje odpowiedź, haszując oryginalny numer jednorazowy i porównując go z wartością przekazaną przez Apple.

  2. Zainicjuj proces logowania Apple przy użyciu biblioteki OAuth lub innej metody. Pamiętaj, aby w żądaniu uwzględnić zahaszowaną wartość jednorazową jako parametr.

  3. Po otrzymaniu odpowiedzi Apple pobierz token ID z odpowiedzi i użyj go oraz niezaszyfrowanego jednorazu, aby utworzyć AuthCredential :

    Java

    AuthCredential credential =  OAuthProvider.newCredentialBuilder("apple.com")
        .setIdTokenWithRawNonce(appleIdToken, rawUnhashedNonce)
        .build();
    

    Kotlin+KTX

    val credential =  OAuthProvider.newCredentialBuilder("apple.com")
        .setIdTokenWithRawNonce(appleIdToken, rawUnhashedNonce)
        .build()
    
  4. Uwierzytelnij się w Firebase przy użyciu poświadczeń Firebase:

    Java

    mAuth.signInWithCredential(credential)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
          @Override
          public void onComplete(@NonNull Task<AuthResult> task) {
            if (task.isSuccessful()) {
              // User successfully signed in with Apple ID token.
              // ...
            }
          }
        });
    

    Kotlin+KTX

    auth.signInWithCredential(credential)
          .addOnCompleteListener(this) { task ->
              if (task.isSuccessful) {
                // User successfully signed in with Apple ID token.
                // ...
              }
          }
    

Jeśli wywołanie signInWithCredential powiedzie się, możesz użyć metody getCurrentUser , aby uzyskać dane konta użytkownika.

Następne kroki

Gdy użytkownik zaloguje się po raz pierwszy, zostanie utworzone nowe konto użytkownika i połączone z poświadczeniami — czyli nazwą użytkownika i hasłem, numerem telefonu lub informacjami o dostawcy uwierzytelniania — za pomocą których użytkownik się zalogował. To nowe konto jest przechowywane jako część projektu Firebase i może służyć do identyfikowania użytkownika w każdej aplikacji w projekcie, niezależnie od tego, jak się on loguje.

  • W swoich aplikacjach możesz uzyskać podstawowe informacje o profilu użytkownika z obiektu FirebaseUser . Zobacz Zarządzanie użytkownikami .

  • W regułach bezpieczeństwa bazy danych czasu rzeczywistego i usługi Cloud Storage Firebase możesz uzyskać unikalny identyfikator zalogowanego użytkownika ze zmiennej auth i używać go do kontrolowania, do jakich danych użytkownik może uzyskać dostęp.

Możesz zezwolić użytkownikom na logowanie się do Twojej aplikacji przy użyciu wielu dostawców uwierzytelniania, łącząc poświadczenia dostawcy uwierzytelniania z istniejącym kontem użytkownika.

Aby wylogować użytkownika, zadzwoń do signOut :

Java

FirebaseAuth.getInstance().signOut();

Kotlin+KTX

Firebase.auth.signOut()