Uwierzytelnij przez Apple na Androidzie

Aby zezwolić użytkownikom na uwierzytelnianie w Firebase za pomocą ich Apple ID: używając pakietu SDK Firebase do przeprowadzenia pełnego logowania OAuth 2.0.

Zanim zaczniesz

Aby zalogować użytkowników przy użyciu urządzenia Apple, najpierw skonfiguruj funkcję Zaloguj się przez Apple w witrynie Apple dla deweloperów, a potem włącz Apple jako dostawcę logowania projekt Firebase.

Dołącz do programu dla deweloperów Apple

Funkcja Zaloguj się przez Apple może skonfigurować tylko członkowie Apple Developer Program.

Skonfiguruj logowanie się przez Apple

Na urządzeniu Apple w witrynie dla deweloperów:

  1. Powiąż witrynę z aplikacją w sposób opisany w pierwszej sekcji z Skonfiguruj funkcję Zaloguj się przez Apple w przeglądarce Gdy pojawi się odpowiedni komunikat, zarejestruj następujący adres URL jako powrotny adres URL:

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

    Identyfikator projektu Firebase znajdziesz w Konsola Firebase stronie ustawień.

    Gdy skończysz, zapisz nowy identyfikator usługi, który będzie Ci potrzebny w przejdź do następnej sekcji.

  2. Utwórz Zaloguj się za pomocą klucza prywatnego Apple. Potrzebujesz nowego klucza prywatnego i klucza Identyfikator znajdziesz w następnej sekcji.
  3. Jeśli używasz dowolnej funkcji Firebase Authentication, która wysyła e-maile do użytkowników, w tym logowanie za pomocą linku e-mail, weryfikacja adresu e-mail, zmiana konta unieważnienie inni, skonfigurować usługę Apple Private Mail relay i zarejestrować noreply@YOUR_FIREBASE_PROJECT_ID.firebaseapp.com (lub dostosowanej domeny szablonu e-maila), dzięki czemu Apple może przekazywać wysyłane e-maile. od Firebase Authentication na zanonimizowane adresy e-mail Apple.

Włącz Apple jako dostawcę logowania

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

Zgodność z wymaganiami firmy Apple dotyczącymi zanonimizowanych danych

Zaloguj się przez Apple umożliwia anonimizację danych użytkowników, łącznie z jego adresem e-mail. Użytkownicy, którzy wybiorą tę opcję mają adresy e-mail w domenie privaterelay.appleid.com. Kiedy korzystasz w aplikacji z funkcji Zaloguj się przez Apple, musisz przestrzegać wszystkich obowiązujących zasady dla deweloperów lub warunki firmy Apple dotyczące tych zanonimizowanych Identyfikatory.

Obejmuje to uzyskanie wymaganej zgody użytkownika przed kojarzyć żadnych danych osobowych bezpośrednio umożliwiających identyfikację ze zanonimizowanymi danymi firmy Apple ID. Gdy korzystasz z Uwierzytelniania Firebase, może to obejmować: czynności:

  • Połącz adres e-mail z anonimowym identyfikatorem Apple ID lub odwrotnie.
  • Łączenie numeru telefonu z anonimowym identyfikatorem Apple ID i odwrotnie
  • Połącz nieanonimowe dane społecznościowe (Facebook, Google itp.) z lub na odwrót.

Powyższa lista nie jest wyczerpująca. Zapoznaj się z informacjami o programie dla deweloperów Apple Umowę licencyjną w sekcji Członkostwo na koncie dewelopera, aby upewnić się, że Twoja aplikacja spełnia wymagania Apple.

Zarejestruj się za pomocą pakietu SDK Firebase

Na urządzeniach z Androidem najłatwiejszym sposobem uwierzytelniania użytkowników w Firebase jest Konta Apple obsługują cały proces logowania za pomocą Firebase na Androida. SDK.

Aby zalogować się za pomocą pakietu SDK Firebase na Androida, wykonaj te czynności:

  1. Zbuduj instancję instancji OAuthProvider za pomocą jego konstruktora identyfikator dostawcy apple.com:

    Kotlin+KTX

    val provider = OAuthProvider.newBuilder("apple.com")
    

    Java

    OAuthProvider.Builder provider = OAuthProvider.newBuilder("apple.com");
    
  2. Opcjonalnie: określ dodatkowe zakresy OAuth 2.0 oprócz domyślnych, które których chcesz żądać od dostawcy uwierzytelniania.

    Kotlin+KTX

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

    Java

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

    Domyślnie, gdy włączona jest opcja jedno konto na adres e-mail, Firebase prosi o zakresy adresów e-mail i nazw. Jeśli zmienisz to ustawienie na Wiele kont na adres e-mail, Firebase nie żąda żadnych zakresów od Apple o ile ich nie określisz.

  3. Opcjonalnie: jeśli chcesz wyświetlać ekran logowania Apple w wybranym języku inny niż angielski, ustaw parametr locale. Zobacz Logowanie się przez Dokumenty Apple w obsługiwanych językach.

    Kotlin+KTX

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

    Java

    // Localize the Apple authentication screen in French.
    provider.addCustomParameter("locale", "fr");
    
  4. Uwierzytelniaj w Firebase za pomocą obiektu dostawcy OAuth. Pamiętaj, że w przeciwieństwie do innych operacji FirebaseAuth, przejmie to kontrolę nad interfejsem użytkownika przez otwórz niestandardową kartę Chrome. Dlatego nie odwołuj się do swojej Aktywności w OnSuccessListener i OnFailureListener, które możesz dołączyć, ponieważ odłączy się od razu po uruchomieniu interfejsu użytkownika.

    Najpierw sprawdź, czy nie wysłaliśmy Ci już odpowiedzi. Logowanie ta metoda umieszcza Twoją aktywność w tle, co oznacza, że może zostać odzyskana przez system podczas logowania. Aby ułatwić aby nie zmuszać użytkownika do ponowienia próby w takim przypadku, sprawdź, czy jest już dostępny wynik.

    Aby sprawdzić, czy jest jakiś oczekujący wynik, zadzwoń pod numer getPendingAuthResult():

    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")
    }
    

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

    Jeśli nie ma żadnych oczekujących wyników, rozpocznij proces logowania, dzwoniąc pod numer startActivityForSignInWithProvider():

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

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

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

    Ponadto, jeśli użytkownik zdecyduje się nie udostępniać aplikacji e-mail, Apple udostępnia danemu użytkownikowi niepowtarzalny adres e-mail (w formie formularza xyz@privaterelay.appleid.com), które udostępnia Twojej aplikacji. Jeśli jeśli skonfigurowano usługę prywatnego przekaźnika poczty e-mail, Apple przekazuje e-maile wysyłane na zanonimizowany adres do rzeczywistego adresu e-mail użytkownika.

    Apple udostępnia informacje o użytkowniku, takie jak wyświetlana nazwa, aplikacjom przy pierwszym logowaniu się użytkownika. Zwykle Firebase przechowuje wyświetlaną nazwę przy pierwszym logowaniu się w Apple. Dzięki temu getCurrentUser().getDisplayName() Jeśli jednak konto Apple było wcześniej używane do logowania użytkownika w aplikacji bez za pomocą Firebase firma Apple nie udostępni Firebase obrazu użytkownika imię i nazwisko.

Ponowne uwierzytelnianie i łączenie kont

Tego samego wzoru można użyć dla atrybutu startActivityForReauthenticateWithProvider() które mogą służyć do pobierania nowych danych logowania na potrzeby operacji poufnych, wymagaj ostatniego logowania:

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.
    })

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

Za pomocą linkWithCredential() możesz też łączyć różnych dostawców tożsamości z istniejących kont.

Pamiętaj, że firma Apple wymaga od użytkowników uzyskania wyraźnej zgody przed połączeniem swoje konta Apple do innych danych.

Aby na przykład połączyć konto na Facebooku z bieżącym kontem Firebase, użyj funkcji token dostępu uzyskany po zalogowaniu użytkownika na Facebooku:

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

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

Zaawansowane: logowanie się ręcznie

Możesz też uwierzytelnić się w Firebase za pomocą konta Apple, obsługując za pomocą pakietu Apple Sign-In JS SDK, ręcznie tworząc lub za pomocą biblioteki OAuth, takiej jak AppAuth.

  1. Dla każdego żądania logowania wygeneruj losowy ciąg znaków, „nonce” – służy do sprawdzenia, czy otrzymany token przyznanych w odpowiedzi na żądanie uwierzytelnienia aplikacji. Ten jest ważny, aby zapobiec atakom typu „replay”.

    Na urządzeniu z Androidem możesz wygenerować szyfrowaną liczbę jednorazową za pomocą SecureRandom jak w tym przykładzie:

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

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

    Następnie pobierz hasz SHA246 liczby jednorazowej w postaci ciągu szesnastkowego:

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

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

    W żądaniu logowania wysyłasz hasz SHA256 identyfikatora jednorazowego, który Apple przekazuje w odpowiedzi niezmienioną treść. Firebase weryfikuje odpowiedź. przez zaszyfrowanie oryginalnej liczby jednorazowej i porównanie jej z wartością przekazaną przez Apple.

  2. Zainicjuj proces logowania Apple przy użyciu biblioteki OAuth lub innej metody. Bądź , uwzględnij zahaszowaną liczbę jednorazową jako parametr w swoim żądaniu.

  3. Gdy otrzymasz odpowiedź Apple, pobierz token identyfikatora z odpowiedzi i użyj go i niezaszyfrowanej liczby jednorazowej do utworzenia AuthCredential:

    Kotlin+KTX

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

    Java

    AuthCredential credential =  OAuthProvider.newCredentialBuilder("apple.com")
        .setIdTokenWithRawNonce(appleIdToken, rawUnhashedNonce)
        .build();
    
  4. Uwierzytelnij w Firebase za pomocą danych logowania Firebase:

    Kotlin+KTX

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

    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.
              // ...
            }
          }
        });
    

Jeśli wywołanie funkcji signInWithCredential się powiedzie, można użyć funkcji getCurrentUser metody pobierania danych z konta użytkownika.

Unieważnienie tokena

Apple wymaga, aby aplikacje umożliwiające tworzenie kont mogły inicjować działania użytkowników usunięcia konta w aplikacji, zgodnie z opisem w Informacjach na temat App Store Wytyczne

Ponadto aplikacje obsługujące funkcję Zaloguj się przez Apple powinny używać funkcji Zaloguj się przez Apple. Interfejs API typu REST do unieważniania tokenów użytkowników.

Aby spełnić to wymaganie, wykonaj następujące czynności:

  1. Użyj metody startActivityForSignInWithProvider(), aby zalogować się za pomocą urządzenia Apple i uzyskać AuthResult.

  2. Uzyskaj token dostępu dla dostawcy Apple.

    Kotlin+KTX

    val oauthCredential: OAuthCredential =  authResult.credential
    val accessToken = oauthCredential.accessToken
    

    Java

    OAuthCredential oauthCredential = (OAuthCredential) authResult.getCredential();
    String accessToken = oauthCredential.getAccessToken();
    
  3. Unieważnij token za pomocą interfejsu API revokeAccessToken.

    Kotlin+KTX

    mAuth.revokeAccessToken(accessToken)
      .addOnCompleteListener(this) { task ->
        if (task.isSuccessful) {
          // Access token successfully revoked
          // for the user ...
        }
    }
    

    Java

    mAuth.revokeAccessToken(accessToken)
        .addOnCompleteListener(this, new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
              if (task.isSuccessful()) {
                // Access token successfully revoked
                // for the user ...
              }
            }
      });
    
  1. Na koniec usuń konto użytkownika (i wszystkie powiązane dane)

    Dalsze kroki

    Gdy użytkownik zaloguje się po raz pierwszy, tworzone jest nowe konto użytkownika. powiązane z danymi logowania, czyli z nazwą użytkownika, hasłem i numerem telefonu, numer telefonu lub informacje o dostawcy uwierzytelniania – użytkownik zalogowany. Ten nowy jest przechowywane w ramach projektu Firebase i może służyć do identyfikowania użytkownika w każdej aplikacji w projekcie, niezależnie od tego, jak się loguje.

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

    • Na liście Firebase Realtime Database i Cloud Storage regułami zabezpieczeń, pobierz ze zmiennej auth unikalny identyfikator zalogowanego użytkownika, i używać ich do kontrolowania, do jakich danych użytkownik ma dostęp.

    Możesz zezwolić użytkownikom na logowanie się w aplikacji przy użyciu wielokrotnego uwierzytelniania. dostawców, łącząc dane logowania dostawcy uwierzytelniania z istniejącego konta użytkownika.

    Aby wylogować użytkownika, wywołaj signOut:

    Kotlin+KTX

    Firebase.auth.signOut()

    Java

    FirebaseAuth.getInstance().signOut();