Autenticar usando Yahoo en plataformas Apple

Puede permitir que sus usuarios se autentiquen con Firebase utilizando proveedores de OAuth como Yahoo integrando el inicio de sesión OAuth genérico en su aplicación utilizando el SDK de Firebase para llevar a cabo el flujo de inicio de sesión de principio a fin.

Antes de que empieces

Para iniciar sesión como usuario con cuentas de Yahoo, primero debes habilitar Yahoo como proveedor de inicio de sesión para tu proyecto de Firebase:

  1. Agrega Firebase a tu proyecto de Apple .
  2. En Firebase console , abre la sección Auth .
  3. En la pestaña Método de inicio de sesión , habilite el proveedor de Yahoo .
  4. Agregue el ID de cliente y el Secreto de cliente desde la consola de desarrollador de ese proveedor a la configuración del proveedor:
    1. Para registrar un cliente Yahoo OAuth, siga la documentación para desarrolladores de Yahoo sobre cómo registrar una aplicación web con Yahoo .

      Asegúrese de seleccionar los dos permisos de la API de OpenID Connect: profile y email .

    2. Al registrar aplicaciones con estos proveedores, asegúrese de registrar el dominio *.firebaseapp.com para su proyecto como dominio de redireccionamiento para su aplicación.
  5. Clic en Guardar .

Maneja el flujo de inicio de sesión con el SDK de Firebase

Para manejar el flujo de inicio de sesión con el SDK de las plataformas Firebase Apple, siga estos pasos:

  1. Agregue esquemas de URL personalizados a su proyecto Xcode:

    1. Abra la configuración de su proyecto: haga doble clic en el nombre del proyecto en la vista de árbol de la izquierda. Seleccione su aplicación en la sección OBJETIVOS , luego seleccione la pestaña Información y expanda la sección Tipos de URL .
    2. Haga clic en el botón + y agregue su ID de aplicación codificada como un esquema de URL. Puede encontrar su ID de aplicación codificada en la página Configuración general de Firebase console, en la sección de su aplicación iOS. Deje los demás campos en blanco.

      Cuando esté completa, su configuración debería verse similar a la siguiente (pero con los valores específicos de su aplicación):

      Captura de pantalla de la interfaz de configuración del esquema de URL personalizado de Xcode

  2. Cree una instancia de OAuthProvider utilizando el ID de proveedor yahoo.com .

    var provider = OAuthProvider(providerID: "yahoo.com")
       
    FIROAuthProvider *provider = [FIROAuthProvider providerWithProviderID:@"yahoo.com"];
       
  3. Opcional : especifique parámetros OAuth personalizados adicionales que desee enviar con la solicitud OAuth.

    provider.customParameters = [
    "prompt": "login",
    "language": "fr"
    ]
       
    [provider setCustomParameters:@{@"prompt": @"login", @"language": @"fr"}];
       

    Para conocer los parámetros que admite Yahoo, consulte la documentación de Yahoo OAuth . Ten en cuenta que no puedes pasar los parámetros requeridos por Firebase con setCustomParameters . Estos parámetros son client_id , redirigir_uri , tipo_respuesta , alcance y estado .

  4. Opcional : especifique alcances de OAuth 2.0 adicionales más allá profile y email que desea solicitar al proveedor de autenticación. Si su aplicación requiere acceso a datos privados de usuario de las API de Yahoo, deberá solicitar permisos para las API de Yahoo en Permisos de API en la consola de desarrollador de Yahoo. Los alcances de OAuth solicitados deben coincidir exactamente con los preconfigurados en los permisos API de la aplicación. Por ejemplo, si se solicita acceso de lectura/escritura a los contactos del usuario y se preconfigura en los permisos API de la aplicación, se debe pasar sdct-w en lugar del alcance OAuth de solo lectura sdct-r . De lo contrario, el flujo fallará y se mostrará un error al usuario final.

    // Request access to Yahoo Mail API.
    // Request read/write access to user contacts.
    // This must be preconfigured in the app's API permissions.
    provider
    .scopes = ["mail-r", "sdct-w"]
       
    // Request access to Yahoo Mail API.
    // Request read/write access to user contacts.
    // This must be preconfigured in the app's API permissions.
    [provider setScopes:@[@"mail-r", @"sdct-w"]];
       

    Para obtener más información, consulte la documentación de alcances de Yahoo .

  5. Opcional : si desea personalizar la forma en que su aplicación presenta SFSafariViewController o UIWebView cuando muestra reCAPTCHA al usuario, cree una clase personalizada que se ajuste al protocolo AuthUIDelegate y pásela a credentialWithUIDelegate .

  6. Autentíquese con Firebase utilizando el objeto proveedor de OAuth.

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

    Con el token de acceso de OAuth, puede llamar a la API de Yahoo .

    Por ejemplo, para obtener información básica del perfil, puede llamar a la API REST y pasar el token de acceso en el encabezado Authorization :

    https://social.yahooapis.com/v1/user/YAHOO_USER_UID/profile?format=json

    Donde YAHOO_USER_UID es el ID del usuario de Yahoo que se puede recuperar del campo Auth.auth.currentUser.providerData[0].uid o de authResult.additionalUserInfo.profile .

  7. Si bien los ejemplos anteriores se centran en los flujos de inicio de sesión, también tiene la posibilidad de vincular un proveedor de Yahoo a un usuario existente mediante linkWithPopup . Por ejemplo, puede vincular varios proveedores al mismo usuario, permitiéndoles iniciar sesión con cualquiera de ellos.

    Auth().currentUser.link(withCredential: credential) { authResult, error in
    if error != nil {
    // Handle error.
    }
    // Yahoo credential is linked to the current user.
    // IdP data available in authResult.additionalUserInfo.profile.
    // Yahoo OAuth access token can also be retrieved by:
    // (authResult.credential as? OAuthCredential)?.accessToken
    // Yahoo OAuth ID token can be retrieved by calling:
    // (authResult.credential as? OAuthCredential)?.idToken
    }
       
    [[FIRAuth auth].currentUser
    linkWithCredential
    :credential
            completion
    :^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
    if (error) {
    // Handle error.
    }
    // Yahoo credential is linked to the current user.
    // IdP data available in authResult.additionalUserInfo.profile.
    // Yahoo OAuth access token is can also be retrieved by:
    // ((FIROAuthCredential *)authResult.credential).accessToken
    // Yahoo OAuth ID token can be retrieved by calling:
    // ((FIROAuthCredential *)authResult.credential).idToken
    }];
       
  8. Se puede usar el mismo patrón con reauthenticateWithPopup / reauthenticateWithRedirect , que se puede usar para recuperar credenciales nuevas para operaciones confidenciales que requieren un inicio de sesión reciente.

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

Si habilitó la configuración Una cuenta por dirección de correo electrónico en Firebase console , cuando un usuario intenta iniciar sesión en un proveedor (como Yahoo) con un correo electrónico que ya existe para el proveedor de otro usuario de Firebase (como Google), aparecerá el error. FIRAuthErrorCodeAccountExistsWithDifferentCredential se lanza junto con un objeto FIRAuthCredential temporal (credencial de Yahoo). Para completar el inicio de sesión con el proveedor deseado, el usuario debe iniciar sesión primero en el proveedor existente (Google) y luego vincularse a la antigua FIRAuthCredential (credencial de Yahoo). Esto quedaría como se ilustra a continuación:

  // 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;
       
}
     
}];
   
}
 
}];
 

A diferencia de otros proveedores de OAuth compatibles con Firebase, como Google, Facebook y Twitter, donde el inicio de sesión se puede lograr directamente con credenciales basadas en tokens de acceso de OAuth, Firebase Auth no admite la misma capacidad para proveedores como Yahoo debido a la incapacidad del Servidor Firebase Auth para verificar la audiencia de los tokens de acceso de Yahoo OAuth. Este es un requisito de seguridad crítico y podría exponer aplicaciones y sitios web a ataques repetidos en los que un token de acceso Yahoo OAuth obtenido para un proyecto (atacante) puede usarse para iniciar sesión en otro proyecto (víctima). En cambio, Firebase Auth ofrece la capacidad de manejar todo el flujo de OAuth y el intercambio de códigos de autorización utilizando el ID y el secreto del cliente de OAuth configurados en Firebase Console. Como el código de autorización solo se puede utilizar junto con un ID/secreto de cliente específico, un código de autorización obtenido para un proyecto no se puede utilizar con otro.

Si es necesario utilizar estos proveedores en entornos no compatibles, se deberá utilizar una biblioteca OAuth de terceros y una autenticación personalizada de Firebase . El primero es necesario para autenticarse con el proveedor y el segundo para intercambiar la credencial del proveedor por un token personalizado.

Próximos pasos

Después de que un usuario inicia sesión por primera vez, se crea una nueva cuenta de usuario y se vincula a las credenciales (es decir, el nombre de usuario y la contraseña, el número de teléfono o la información del proveedor de autenticación) con las que el usuario inició sesión. Esta nueva cuenta se almacena como parte de su proyecto de Firebase y se puede usar para identificar a un usuario en cada aplicación de su proyecto, independientemente de cómo inicie sesión el usuario.

  • En sus aplicaciones, puede obtener la información básica del perfil del usuario desde el objeto User . Consulte Administrar usuarios .

  • En las reglas de seguridad de Firebase Realtime Database y Cloud Storage, puede obtener el ID de usuario único del usuario que inició sesión a partir de la variable auth y usarlo para controlar a qué datos puede acceder un usuario.

Puede permitir que los usuarios inicien sesión en su aplicación utilizando múltiples proveedores de autenticación vinculando las credenciales del proveedor de autenticación a una cuenta de usuario existente.

Para cerrar la sesión de un usuario, llame 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;
}

Es posible que también desee agregar un código de manejo de errores para toda la gama de errores de autenticación. Consulte Manejar errores .