Uwierzytelniaj za pomocą OpenID Connect na urządzeniu z Androidem

Po przejściu na Uwierzytelnianie Firebase z Identity Platform możesz uwierzytelniać użytkowników w Firebase za pomocą wybranego dostawcy zgodnego z OpenID Connect (OIDC). Umożliwia to korzystanie z dostawców tożsamości, które nie są natywnie obsługiwane przez Firebase.

Zanim zaczniesz

Aby zalogować użytkowników przy użyciu dostawcy OIDC, musisz najpierw uzyskać od niego pewne informacje:

  • Identyfikator klienta: unikalny ciąg znaków identyfikujący Twoją aplikację. Dostawca może przypisać Ci inny identyfikator klienta dla każdej obsługiwanej platformy. To jedna z wartości deklaracji aud w tokenach identyfikatorów wystawionych przez Twojego dostawcę.

  • Tajny klucz klienta: ciąg tajny używany przez dostawcę do potwierdzania własności identyfikatora klienta. Do każdego identyfikatora klienta musi być dopasowany tajny klucz klienta. (Ta wartość jest wymagana tylko w przypadku korzystania z przepływu kodu uwierzytelniającego, co jest zdecydowanie zalecane).

  • Wystawca: ciąg znaków identyfikujący dostawcę. Ta wartość musi być adresem URL, który po dodaniu do /.well-known/openid-configuration jest lokalizacją dokumentu wykrywania OIDC dostawcy. Jeśli na przykład wydawcą jest https://auth.example.com, dokument opisujący musi być dostępny na stronie https://auth.example.com/.well-known/openid-configuration.

Po otrzymaniu tych informacji włącz OpenID Connect jako dostawcę logowania w projekcie Firebase:

  1. Dodaj Firebase do swojego projektu na Androida.

  2. Jeśli nie korzystasz jeszcze z Uwierzytelniania Firebase z Identity Platform, zrób to. Uwierzytelnianie OpenID Connect jest dostępne tylko w uaktualnionych projektach.

  3. Na stronie Sign-in provider (Dostawcy logowania) w konsoli Firebase kliknij Dodaj nowego dostawcę, a następnie kliknij OpenID Connect.

  4. Wybierz, czy będziesz korzystać z przepływu kodu autoryzacji czy przepływu niejawnego uwierzytelnienia.

    Należy zawsze używać przepływu kodu, jeśli dostawca go obsługuje. Ten przepływ pośredni jest mniej bezpieczny i zdecydowanie odradzamy jego używanie.

  5. Nazwij tego dostawcę. Zanotuj wygenerowany identyfikator dostawcy, np. oidc.example-provider. Będzie Ci potrzebny podczas dodawania kodu logowania do aplikacji.

  6. Podaj swój identyfikator klienta i tajny klucz klienta oraz ciąg znaków wydawcy dostawcy. Te wartości muszą dokładnie odpowiadać wartościom przypisanym przez dostawcę.

  7. Zapisz zmiany.

Zarejestruj się za pomocą pakietu SDK Firebase

Jeśli tworzysz aplikację na Androida, najprostszym sposobem uwierzytelniania użytkowników w Firebase przy użyciu dostawcy OIDC jest obsługa całego procesu logowania za pomocą pakietu SDK Firebase na Androida.

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

  1. Utwórz instancję dostawcy OAuthProvider za pomocą jego elementu Builder z identyfikatorem dostawcy

    Kotlin+KTX

    val providerBuilder = OAuthProvider.newBuilder("oidc.example-provider")

    Java

    OAuthProvider.Builder providerBuilder = OAuthProvider.newBuilder("oidc.example-provider");

  2. Opcjonalnie: określ dodatkowe niestandardowe parametry OAuth, które chcesz wysyłać z żądaniem OAuth.

    Kotlin+KTX

    // Target specific email with login hint.
    providerBuilder.addCustomParameter("login_hint", "[email protected]")

    Java

    // Target specific email with login hint.
    providerBuilder.addCustomParameter("login_hint", "[email protected]");

    Skontaktuj się z dostawcą OIDC, aby poznać obsługiwane parametry. Pamiętaj, że za pomocą setCustomParameters() nie możesz przekazywać parametrów wymaganych przez Firebase. Są to: client_id, response_type, redirect_uri, state, scope i response_mode.

  3. Opcjonalnie: określ dodatkowe zakresy OAuth 2.0 poza podstawowym profilem, o które chcesz poprosić dostawcę uwierzytelniania.

    Kotlin+KTX

    // Request read access to a user's email addresses.
    // This must be preconfigured in the app's API permissions.
    providerBuilder.scopes = listOf("mail.read", "calendars.read")

    Java

    // Request read access to a user's email addresses.
    // This must be preconfigured in the app's API permissions.
    List<String> scopes =
            new ArrayList<String>() {
                {
                    add("mail.read");
                    add("calendars.read");
                }
            };
    providerBuilder.setScopes(scopes);

    Skontaktuj się z dostawcą OIDC, aby dowiedzieć się, jakich zakresów używa.

  4. Uwierzytelniaj w Firebase za pomocą obiektu dostawcy OAuth. Pamiętaj, że w przeciwieństwie do innych działań FirebaseAuth będziesz mieć kontrolę nad interfejsem użytkownika, ponieważ wyświetli się niestandardowa karta Chrome. Dlatego nie odwołuj się do aktywności w załącznikach OnSuccessListener i OnFailureListener, ponieważ zostaną one odłączone od razu po uruchomieniu operacji.

    Najpierw sprawdź, czy nie wysłaliśmy Ci już odpowiedzi. Gdy zalogujesz się za pomocą tej metody, Twoja aktywność będzie działać w tle, co oznacza, że system może ją odzyskać podczas logowania. Aby mieć pewność, że użytkownik nie będzie próbował ponownie go znaleźć, sprawdź, czy nie pojawił się już jakiś wynik.

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

    Kotlin+KTX

    val pendingResultTask = firebaseAuth.pendingAuthResult
    if (pendingResultTask != null) {
        // There's something already here! Finish the sign-in for your user.
        pendingResultTask
            .addOnSuccessListener {
                // User is signed in.
                // IdP data available in
                // authResult.getAdditionalUserInfo().getProfile().
                // The OAuth access token can also be retrieved:
                // ((OAuthCredential)authResult.getCredential()).getAccessToken().
                // The OAuth secret can be retrieved by calling:
                // ((OAuthCredential)authResult.getCredential()).getSecret().
            }
            .addOnFailureListener {
                // Handle failure.
            }
    } else {
        // There's no pending result so you need to start the sign-in flow.
        // See below.
    }

    Java

    Task<AuthResult> pendingResultTask = firebaseAuth.getPendingAuthResult();
    if (pendingResultTask != null) {
        // There's something already here! Finish the sign-in for your user.
        pendingResultTask
                .addOnSuccessListener(
                        new OnSuccessListener<AuthResult>() {
                            @Override
                            public void onSuccess(AuthResult authResult) {
                                // User is signed in.
                                // IdP data available in
                                // authResult.getAdditionalUserInfo().getProfile().
                                // The OAuth access token can also be retrieved:
                                // ((OAuthCredential)authResult.getCredential()).getAccessToken().
                                // The OAuth secret can be retrieved by calling:
                                // ((OAuthCredential)authResult.getCredential()).getSecret().
                            }
                        })
                .addOnFailureListener(
                        new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                // Handle failure.
                            }
                        });
    } else {
        // There's no pending result so you need to start the sign-in flow.
        // See below.
    }

    Aby rozpocząć procedurę logowania, zadzwoń pod numer startActivityForSignInWithProvider:

    Kotlin+KTX

    firebaseAuth
        .startActivityForSignInWithProvider(activity, provider.build())
        .addOnSuccessListener {
            // User is signed in.
            // IdP data available in
            // authResult.getAdditionalUserInfo().getProfile().
            // The OAuth access token can also be retrieved:
            // ((OAuthCredential)authResult.getCredential()).getAccessToken().
            // The OAuth secret can be retrieved by calling:
            // ((OAuthCredential)authResult.getCredential()).getSecret().
        }
        .addOnFailureListener {
            // Handle failure.
        }

    Java

    firebaseAuth
            .startActivityForSignInWithProvider(/* activity= */ this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // User is signed in.
                            // IdP data available in
                            // authResult.getAdditionalUserInfo().getProfile().
                            // The OAuth access token can also be retrieved:
                            // ((OAuthCredential)authResult.getCredential()).getAccessToken().
                            // The OAuth secret can be retrieved by calling:
                            // ((OAuthCredential)authResult.getCredential()).getSecret().
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            // Handle failure.
                        }
                    });

  5. Powyższe przykłady koncentrują się na procesach logowania, ale możesz też połączyć dostawcę OIDC z dotychczasowym użytkownikiem za pomocą startActivityForLinkWithProvider. Możesz na przykład połączyć kilku dostawców z tym samym użytkownikiem, umożliwiając im logowanie się za pomocą dowolnej z tych usług.

    Kotlin+KTX

    // The user is already signed-in.
    val firebaseUser = firebaseAuth.currentUser!!
    firebaseUser
        .startActivityForLinkWithProvider(activity, provider.build())
        .addOnSuccessListener {
            // Provider credential is linked to the current user.
            // IdP data available in
            // authResult.getAdditionalUserInfo().getProfile().
            // The OAuth access token can also be retrieved:
            // authResult.getCredential().getAccessToken().
            // The OAuth secret can be retrieved by calling:
            // authResult.getCredential().getSecret().
        }
        .addOnFailureListener {
            // Handle failure.
        }

    Java

    // The user is already signed-in.
    FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
    
    firebaseUser
            .startActivityForLinkWithProvider(/* activity= */ this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // Provider credential is linked to the current user.
                            // IdP data available in
                            // authResult.getAdditionalUserInfo().getProfile().
                            // The OAuth access token can also be retrieved:
                            // authResult.getCredential().getAccessToken().
                            // The OAuth secret can be retrieved by calling:
                            // authResult.getCredential().getSecret().
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            // Handle failure.
                        }
                    });

  6. Tego samego wzorca można używać z funkcją startActivityForReauthenticateWithProvider, która umożliwia pobieranie nowych danych logowania w przypadku poufnych operacji wymagających niedawnego logowania.

    Kotlin+KTX

    // The user is already signed-in.
    val firebaseUser = firebaseAuth.currentUser!!
    firebaseUser
        .startActivityForReauthenticateWithProvider(activity, provider.build())
        .addOnSuccessListener {
            // User is re-authenticated with fresh tokens and
            // should be able to perform sensitive operations
            // like account deletion and email or password
            // update.
        }
        .addOnFailureListener {
            // Handle failure.
        }

    Java

    // The user is already signed-in.
    FirebaseUser firebaseUser = firebaseAuth.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.
                        }
                    });

Zarejestruj się ręcznie

Jeśli masz już wdrożony w aplikacji proces logowania OpenID Connect, możesz użyć tokena identyfikatora bezpośrednio, by uwierzytelnić się w Firebase:

Kotlin+KTX

val providerId = "oidc.example-provider" // As registered in Firebase console.
val credential = oAuthCredential(providerId) {
    setIdToken(idToken) // ID token from OpenID Connect flow.
}
Firebase.auth
    .signInWithCredential(credential)
    .addOnSuccessListener { authResult ->
        // User is signed in.

        // IdP data available in:
        //    authResult.additionalUserInfo.profile
    }
    .addOnFailureListener { e ->
        // Handle failure.
    }

Java

AuthCredential credential = OAuthProvider
        .newCredentialBuilder("oidc.example-provider")  // As registered in Firebase console.
        .setIdToken(idToken)  // ID token from OpenID Connect flow.
        .build();
FirebaseAuth.getInstance()
        .signInWithCredential(credential)
        .addOnSuccessListener(new OnSuccessListener<AuthResult>() {
            @Override
            public void onSuccess(AuthResult authResult) {
                // User is signed in.

                // IdP data available in:
                //    authResult.getAdditionalUserInfo().getProfile()
            }
        })
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                // Handle failure.
            }
        });

Dalsze kroki

Gdy użytkownik loguje się po raz pierwszy, tworzone jest nowe konto użytkownika, które jest łączone z danymi logowania (nazwa użytkownika i hasło, numer telefonu lub informacje o dostawcy uwierzytelniania). Nowe konto jest przechowywane w ramach Twojego projektu Firebase i może być używane do identyfikowania użytkowników we wszystkich aplikacjach w Twoim projekcie niezależnie od tego, jak się on loguje.

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

  • W regułach zabezpieczeń Bazy danych czasu rzeczywistego Firebase i Cloud Storage możesz pobrać ze zmiennej auth unikalny identyfikator użytkownika zalogowanego użytkownika i użyć go do kontrolowania, do jakich danych użytkownik ma dostęp.

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

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

Kotlin+KTX

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();