Uwierzytelniaj za pomocą Twittera na platformach Apple

Możesz umożliwić użytkownikom uwierzytelnianie się w Firebase za pomocą dostawców OAuth, takich jak Twitter. W tym celu zintegruj ogólne logowanie OAuth z aplikacją za pomocą pakietu SDK Firebase, aby przeprowadzić cały proces logowania.

Zanim zaczniesz

Do instalacji zależności Firebase i zarządzania nimi możesz używać menedżera pakietów Swift.

  1. Po otwarciu projektu aplikacji w Xcode wybierz Plik > Dodaj pakiety.
  2. Gdy pojawi się prośba, dodaj repozytorium pakietu SDK Firebase na platformy Apple:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. Wybierz bibliotekę Firebase Authentication.
  5. Dodaj flagę -ObjC do sekcji Inne flagi linkera w ustawieniach kompilacji docelowej.
  6. Gdy to zrobisz, Xcode automatycznie zacznie wyszukiwać i pobierać zależności w tle.

Aby umożliwić użytkownikom logowanie się za pomocą kont Twittera, musisz najpierw włączyć Twittera jako dostawcę logowania w projekcie Firebase:

  1. Dodaj Firebase do projektu Apple.

  2. Podfile uwzględnij te elementy:

    pod 'FirebaseAuth'
  3. W konsoli Firebase otwórz sekcję Uwierzytelnianie.
  4. Na karcie Metoda logowania włącz dostawcę Twitter.
  5. Dodaj klucz APItajny klucz API z konsoli deweloperów tego dostawcy do konfiguracji tego dostawcy:
    1. Zarejestruj aplikację jako aplikacja dewelopera w Twitterze i uzyskaj klucz API oraz tajny klucz API aplikacji.
    2. Upewnij się, że identyfikator URI przekierowania OAuth w Firebase (np. my-app-12345.firebaseapp.com/__/auth/handler) jest ustawiony jako adres URL wywołania zwrotnego autoryzacji na stronie ustawień aplikacji na stronie konfiguracji aplikacji Twitter.
  6. Kliknij Zapisz.

Obsługa procesu logowania za pomocą pakietu SDK Firebase

Aby obsłużyć proces logowania za pomocą pakietu SDK Firebase na platformy Apple, wykonaj te czynności:

  1. Dodawanie niestandardowych schematów adresów URL do projektu Xcode:

    1. Otwórz konfigurację projektu: kliknij dwukrotnie nazwę projektu w widoku drzewa po lewej stronie. W sekcji CELE wybierz swoją aplikację, a potem kliknij kolejno karty InformacjeTypy adresów URL.
    2. Kliknij przycisk + i dodaj zakodowany identyfikator aplikacji jako schemat adresu URL. Zaszyfrowany identyfikator aplikacji znajdziesz na stronie Ustawienia ogólne w konsoli Firebase, w sekcji dotyczącej aplikacji na iOS. Pozostaw puste pozostałe pola.

      Po zakończeniu konfiguracja powinna wyglądać mniej więcej tak (ale z wartościami odpowiednimi dla Twojej aplikacji):

      Zrzut ekranu interfejsu konfiguracji niestandardowego schematu URL w Xcode

  2. Utwórz instancję interfejsu OAuthProvider, używając identyfikatora dostawcy twitter.com.

        var provider = OAuthProvider(providerID: "twitter.com")
        
        FIROAuthProvider *provider = [FIROAuthProvider providerWithProviderID:@"twitter.com"];
        
  3. Opcjonalnie: określ dodatkowe niestandardowe parametry OAuth, które chcesz wysłać z żądaniem OAuth.

        provider.customParameters = [
          "lang": "fr"
          ]
        
        [provider setCustomParameters:@{@"lang": @"fr"}];
        

    Informacje o parametrach obsługiwanych przez Twittera znajdziesz w dokumentacji Twittera na temat OAuth. Pamiętaj, że za pomocą parametru setCustomParameters nie możesz przekazywać parametrów wymaganych przez Firebase. Są to: client_id, redirect_uri, response_type, scopestate.

  4. Opcjonalnie: jeśli chcesz dostosować sposób wyświetlania przez aplikację informacji SFSafariViewController lub UIWebView podczas wyświetlania reCAPTCHA użytkownikowi, utwórz klasę niestandardową zgodną z protokołem AuthUIDelegate i przekaż ją do funkcji credentialWithUIDelegate.

  5. Uwierzytelnij się w Firebase, używając obiektu dostawcy OAuth.

        provider.getCredentialWith(nil) { credential, error in
          if error != nil {
            // Handle error.
          }
          if credential != nil {
            Auth.auth().signIn(with: credential) { authResult, error in
              if error != nil {
                // Handle error.
              }
              // User is signed in.
              // IdP data available in authResult.additionalUserInfo.profile.
              // Twitter OAuth access token can also be retrieved by:
              // (authResult.credential as? OAuthCredential)?.accessToken
              // Twitter OAuth ID token can be retrieved by calling:
              // (authResult.credential as? OAuthCredential)?.idToken
              // Twitter OAuth secret can be retrieved by calling:
              // (authResult.credential as? OAuthCredential)?.secret
            }
          }
        }
        
        [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.
              // Twitter OAuth access token can also be retrieved by:
              // authResult.credential.accessToken
              // Twitter OAuth ID token can be retrieved by calling:
              // authResult.credential.idToken
              // Twitter OAuth secret can be retrieved by calling:
              // authResult.credential.secret
            }];
          }
        }];
        

    Za pomocą tokena dostępu OAuth możesz wywoływać interfejs Twitter API.

    Aby na przykład uzyskać podstawowe informacje o profilu, możesz wywołać interfejs API REST, przekazując token dostępu w nagłówku Authorization:

    https://api.twitter.com/labs/1/users?usernames=TwitterDev
  6. Powyższe przykłady koncentrują się na procesach logowania, ale możesz też połączyć dostawcę Twittera z dotychczasowym użytkownikiem. Możesz na przykład połączyć wielu dostawców z jednym użytkownikiem, aby umożliwić mu logowanie się za pomocą dowolnego z nich.

        Auth().currentUser.link(withCredential: credential) { authResult, error in
          if error != nil {
            // Handle error.
          }
          // Twitter credential is linked to the current user.
          // IdP data available in authResult.additionalUserInfo.profile.
          // Twitter OAuth access token can also be retrieved by:
          // (authResult.credential as? OAuthCredential)?.accessToken
          // Twitter OAuth ID token can be retrieved by calling:
          // (authResult.credential as? OAuthCredential)?.idToken
          // Twitter OAuth secret can be retrieved by calling:
          // (authResult.credential as? OAuthCredential)?.secret
        }
        
        [[FIRAuth auth].currentUser
            linkWithCredential:credential
                    completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
          if (error) {
            // Handle error.
          }
          // Twitter credential is linked to the current user.
          // IdP data available in authResult.additionalUserInfo.profile.
          // Twitter OAuth access token is can also be retrieved by:
          // ((FIROAuthCredential *)authResult.credential).accessToken
          // Twitter OAuth ID token can be retrieved by calling:
          // ((FIROAuthCredential *)authResult.credential).idToken
          // Twitter OAuth secret can be retrieved by calling:
          // ((FIROAuthCredential *)authResult.credential).secret
        }];
        
  7. Tego samego schematu można używać w przypadku funkcji reauthenticateWithCredential, która może służyć do pobierania nowych danych logowania w przypadku operacji związanych z poufnymi danymi, które wymagają niedawnego zalogowania.

        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 is can also be retrieved by:
          // (authResult.credential as? OAuthCredential)?.accessToken
          // Twitter OAuth ID token can be retrieved by calling:
          // (authResult.credential as? OAuthCredential)?.idToken
          // Twitter OAuth secret can be retrieved by calling:
          // (authResult.credential as? OAuthCredential)?.secret
        }
        
        [[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 is can also be retrieved by:
          // ((FIROAuthCredential *)authResult.credential).accessToken
          // Twitter OAuth ID token can be retrieved by calling:
          // ((FIROAuthCredential *)authResult.credential).idToken
          // Twitter OAuth secret can be retrieved by calling:
          // ((FIROAuthCredential *)authResult.credential).secret
        }];
        

Jeśli w konsoli Firebase włączysz ustawienie Jedno konto na adres e-mail, gdy użytkownik spróbuje zalogować się u dostawcy (np. Twittera) za pomocą adresu e-mail, który jest już używany przez innego użytkownika Firebase (np. Google), zostanie zgłoszony błądFIRAuthErrorCodeAccountExistsWithDifferentCredential wraz z tymczasowym obiektem FIRAuthCredential (dane logowania Twittera). Aby dokończyć logowanie do wybranego dostawcy, użytkownik musi najpierw zalogować się na konto dotychczasowego dostawcy (Google), a następnie połączyć je z FIRAuthCredential (dane logowania Twittera). Wyglądałoby to tak:

  // Sign-in with an OAuth credential.
  provider.getCredentialWith(nil) { credential, error in
    // An account with the same email already exists.
    if (error as NSError?)?.code == AuthErrorCode.accountExistsWithDifferentCredential.rawValue {
      // Get pending credential and email of existing account.
      let existingAcctEmail = (error! as NSError).userInfo[AuthErrorUserInfoEmailKey] as! String
      let pendingCred = (error! as NSError).userInfo[AuthErrorUserInfoUpdatedCredentialKey] as! AuthCredential
      // Lookup existing account identifier by the email.
      Auth.auth().fetchProviders(forEmail:existingAcctEmail) { providers, error in
        // Existing email/password account.
        if (providers?.contains(EmailAuthProviderID))! {
          // Existing password account for email. Ask user to provide the password of the
          // existing account.
          // Sign in with existing account.
          Auth.auth().signIn(withEmail:existingAcctEmail, password:password) { user, error in
            // Successfully signed in.
            if user != nil {
              // Link pending credential to account.
              Auth.auth().currentUser?.linkAndRetrieveData(with: pendingCred) { result, error in
                // ...
              }
            }
          }
        }
      }
      return
    }

    // Other errors.
    if error != nil {
      // handle the error.
      return
    }

    // Sign in with the credential.
    if credential != nil {
      Auth.auth().signInAndRetrieveData(with: credential!) { result, error in
        if error != nil {
          // handle the error.
          return
        }
      }
    }
  }

  
  // Sign-in with an OAuth credential.
  [provider getCredentialWithUIDelegate:nil
                             completion:^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error) {
    // An account with the same email already exists.
    if (error.code == FIRAuthErrorCodeAccountExistsWithDifferentCredential) {
      // Get pending credential and email of existing account.
      NSString *existingAcctEmail = error.userInfo[FIRAuthErrorUserInfoEmailKey];
      FIRAuthCredential *pendingCred = error.userInfo[FIRAuthErrorUserInfoUpdatedCredentialKey];
      // Lookup existing account identifier by the email.
      [[FIRAuth auth] fetchProvidersForEmail:existingAcctEmail
                                 completion:^(NSArray<NSString *> *_Nullable providers,
                                              NSError *_Nullable error) {
        // Existing email/password account.
        if ( [providers containsObject:FIREmailAuthProviderID] ) {
          // Existing password account for email. Ask user to provide the password of the
          // existing account.

          // Sign in with existing account.
          [[FIRAuth auth] signInWithEmail:existingAcctEmail
                                 password:password
                               completion:^(FIRUser *user, NSError *error) {
            // Successfully signed in.
            if (user) {
              // Link pending credential to account.
              [[FIRAuth auth].currentUser linkWithCredential:pendingCred
                                                  completion:^(FIRUser *_Nullable user,
                                                               NSError *_Nullable error) {
                // ...
              }];
            }
          }];
        }
      }];
      return;
    }

    // Other errors.
    if (error) {
      // handle the error.
      return;
    }

    // Sign in with the credential.
    if (credential) {
      [[FIRAuth auth] signInAndRetrieveDataWithCredential:credential
          completion:^(FIRAuthDataResult *_Nullable authResult,
                       NSError *_Nullable error) {
        if (error) {
          // handle the error.
          return;
        }
      }];
    }
  }];
  

Dalsze kroki

Gdy użytkownik zaloguje się po raz pierwszy, zostanie utworzone nowe konto użytkownika i połączone z danymi logowania, czyli nazwą użytkownika i hasłem, numerem telefonu lub informacjami dostawcy uwierzytelniania. To nowe konto jest przechowywane w projekcie Firebase i może służyć do identyfikowania użytkownika we wszystkich aplikacjach w projekcie, niezależnie od tego, jak użytkownik się loguje.

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

  • W regułach Firebase Realtime DatabaseCloud Storage Regułach bezpieczeństwa możesz pobrać z zmiennej auth unikalny identyfikator zalogowanego użytkownika i użyć go do kontrolowania dostępu użytkownika do danych.

Możesz zezwolić użytkownikom na logowanie się w aplikacji za pomocą danych logowania od wielu dostawców uwierzytelniania, połączając je z dotychczasowym kontem użytkownika.

Aby wylogować użytkownika, zadzwoń pod numer signOut:.

let firebaseAuth = Auth.auth()
do {
  try firebaseAuth.signOut()
} catch let signOutError as NSError {
  print("Error signing out: %@", signOutError)
}
NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status) {
  NSLog(@"Error signing out: %@", signOutError);
  return;
}

Możesz też dodać kod do obsługi błędów w całym zakresie błędów uwierzytelniania. Zobacz Obsługa błędów.