Uwierzytelniaj za pomocą OpenID Connect na platformach Apple

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 iOS.

  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

Najprostszym sposobem uwierzytelniania użytkowników w Firebase za pomocą dostawcy OIDC jest obsługa całego procesu logowania za pomocą pakietu SDK Firebase.

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

  1. Dodaj niestandardowe schematy adresów URL do projektu Xcode:

    1. Otwórz konfigurację projektu: kliknij dwukrotnie nazwę projektu w widoku drzewa po lewej stronie. Wybierz aplikację w sekcji CELE, kliknij kartę Informacje i rozwiń sekcję Typy adresów URL.
    2. Kliknij przycisk + i dodaj zakodowany identyfikator aplikacji jako schemat adresu URL. Zakodowany identyfikator aplikacji znajdziesz na stronie Ustawienia ogólne konsoli Firebase, w sekcji dotyczącej aplikacji na iOS. Pozostałe pola pozostaw puste.

      Po zakończeniu konfiguracja powinna wyglądać podobnie do tej (ale z wartościami dotyczącymi aplikacji):

      Zrzut ekranu interfejsu konfiguracji niestandardowego schematu adresu URL Xcode
  2. Utwórz instancję OAuthProvider, używając identyfikatora dostawcy uzyskanego w konsoli Firebase.

    Swift

    var provider = OAuthProvider(providerID: "oidc.example-provider")
    

    Objective-C

    FIROAuthProvider *provider = [FIROAuthProvider providerWithProviderID:@"oidc.example-provider"];
    
  3. Opcjonalnie: określ dodatkowe niestandardowe parametry OAuth, które chcesz wysyłać z żądaniem OAuth.

    Swift

    provider.customParameters = [
      "login_hint": "user@example.com"
    ]
    

    Objective-C

    [provider setCustomParameters:@{@"login_hint": @"user@example.com"}];
    

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

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

    Swift

    provider.scopes = ["mail.read", "calendars.read"]
    

    Objective-C

    [provider setScopes:@[@"mail.read", @"calendars.read"]];
    

    Skontaktuj się z dostawcą, aby uzyskać informacje o obsługiwanych zakresach.

  5. Opcjonalnie: jeśli chcesz dostosować sposób, w jaki aplikacja prezentuje SFSafariViewController lub UIWebView podczas wyświetlania użytkownikowi reCAPTCHA, utwórz klasę niestandardową zgodną z protokołem AuthUIDelegate.

  6. Uwierzytelniaj w Firebase za pomocą obiektu dostawcy OAuth.

    Swift

    // If you created a custom class that conforms to AuthUIDelegate,
    // pass it instead of nil:
    provider.getCredentialWith(nil) { credential, error in
      if error != nil {
        // Handle error.
      }
      if credential != nil {
        Auth().signIn(with: credential) { authResult, error in
          if error != nil {
            // Handle error.
          }
          // User is signed in.
          // IdP data available in authResult.additionalUserInfo.profile.
          // OAuth access token can also be retrieved:
          // (authResult.credential as? OAuthCredential)?.accessToken
          // OAuth ID token can also be retrieved:
          // (authResult.credential as? OAuthCredential)?.idToken
        }
      }
    }
    

    Objective-C

    // If you created a custom class that conforms to AuthUIDelegate,
    // pass it instead of nil:
    [provider getCredentialWithUIDelegate:nil
                                completion:^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error) {
      if (error) {
        // Handle error.
      }
      if (credential) {
        [[FIRAuth auth] signInWithCredential:credential
                                  completion:^(FIRAuthDataResult *_Nullable authResult, NSError *_Nullable error) {
          if (error) {
            // Handle error.
          }
          // User is signed in.
          // IdP data available in authResult.additionalUserInfo.profile.
          // OAuth access token can also be retrieved:
          // ((FIROAuthCredential *)authResult.credential).accessToken
          // OAuth ID token can also be retrieved:
          // ((FIROAuthCredential *)authResult.credential).idToken
        }];
      }
    }];
    
  7. Powyższe przykłady koncentrują się na procesach logowania, ale możesz też połączyć dostawcę OIDC z dotychczasowym użytkownikiem za pomocą linkWithCredential. 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.

    Swift

    Auth().currentUser.link(withCredential: credential) { authResult, error in
      if error != nil {
        // Handle error.
      }
      // OIDC credential is linked to the current user.
      // IdP data available in authResult.additionalUserInfo.profile.
      // OAuth access token can also be retrieved:
      // (authResult.credential as? OAuthCredential)?.accessToken
      // OAuth ID token can also be retrieved:
      // (authResult.credential as? OAuthCredential)?.idToken
    }
    

    Objective-C

    [[FIRAuth auth].currentUser
        linkWithCredential:credential
                completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
      if (error) {
        // Handle error.
      }
      // OIDC credential is linked to the current user.
      // IdP data available in authResult.additionalUserInfo.profile.
      // OAuth access token can also be retrieved:
      // ((FIROAuthCredential *)authResult.credential).accessToken
      // OAuth ID token can also be retrieved:
      // ((FIROAuthCredential *)authResult.credential).idToken
    }];
    
  8. Tego samego wzorca można używać z funkcją reauthenticateWithCredential, która umożliwia pobieranie nowych danych logowania na potrzeby poufnych operacji, które wymagają niedawnego logowania.

    Swift

    Auth().currentUser.reauthenticateWithCredential(withCredential: credential) { authResult, error in
      if error != nil {
        // Handle error.
      }
      // User is re-authenticated with fresh tokens minted and
      // should be able to perform sensitive operations like account
      // deletion and email or password update.
      // IdP data available in result.additionalUserInfo.profile.
      // Additional OAuth access token can also be retrieved:
      // (authResult.credential as? OAuthCredential)?.accessToken
      // OAuth ID token can also be retrieved:
      // (authResult.credential as? OAuthCredential)?.idToken
    }
    

    Objective-C

    [[FIRAuth auth].currentUser
        reauthenticateWithCredential:credential
                          completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
      if (error) {
        // Handle error.
      }
      // User is re-authenticated with fresh tokens minted and
      // should be able to perform sensitive operations like account
      // deletion and email or password update.
      // IdP data available in result.additionalUserInfo.profile.
      // Additional OAuth access token can also be retrieved:
      // ((FIROAuthCredential *)authResult.credential).accessToken
      // OAuth ID token can also be retrieved:
      // ((FIROAuthCredential *)authResult.credential).idToken
    }];
    

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:

Swift

let credential = OAuthProvider.credential(
    withProviderID: "oidc.example-provider",  // As registered in Firebase console.
    idToken: idToken,  // ID token from OpenID Connect flow.
    rawNonce: nil
)
Auth.auth().signIn(with: credential) { authResult, error in
    if error {
        // Handle error.
        return
    }
    // User is signed in.
    // IdP data available in authResult?.additionalUserInfo?.profile
}

Objective-C

FIROAuthCredential *credential =
    [FIROAuthProvider credentialWithProviderID:@"oidc.example-provider"  // As registered in Firebase console.
                                       IDToken:idToken  // ID token from OpenID Connect flow.
                                      rawNonce:nil];
[[FIRAuth auth] signInWithCredential:credential
                          completion:^(FIRAuthDataResult * _Nullable authResult,
                                      NSError * _Nullable error) {
    if (error != nil) {
        // Handle error.
        return;
    }
    // User is signed in.
    // IdP data available in authResult.additionalUserInfo.profile
}];

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 User . Zobacz 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:.

Swift

let firebaseAuth = Auth.auth()
do {
  try firebaseAuth.signOut()
} catch let signOutError as NSError {
  print("Error signing out: %@", signOutError)
}

Objective-C

NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status) {
  NSLog(@"Error signing out: %@", signOutError);
  return;
}

Możesz też dodać kod obsługi błędów dla pełnego zakresu błędów uwierzytelniania. Patrz sekcja Obsługa błędów.