Autenticar usando OpenID Connect en plataformas Apple

Si actualizó a Firebase Authentication con Identity Platform, puede autenticar a sus usuarios con Firebase utilizando el proveedor compatible con OpenID Connect (OIDC) de su elección. Esto hace posible utilizar proveedores de identidades que Firebase no admite de forma nativa.

Antes de que empieces

Para iniciar sesión como usuario utilizando un proveedor OIDC, primero debe recopilar cierta información del proveedor:

  • ID de cliente : una cadena exclusiva del proveedor que identifica su aplicación. Su proveedor podría asignarle una ID de cliente diferente para cada plataforma que admita. Este es uno de los valores del reclamo aud en tokens de identificación emitidos por su proveedor.

  • Secreto del cliente : una cadena secreta que el proveedor utiliza para confirmar la propiedad de un ID de cliente. Para cada ID de cliente, necesitará un secreto de cliente coincidente. (Este valor solo es obligatorio si utiliza el flujo de código de autenticación , lo cual es muy recomendable).

  • Emisor : una cadena que identifica a su proveedor. Este valor debe ser una URL que, cuando se añade /.well-known/openid-configuration , sea la ubicación del documento de descubrimiento OIDC del proveedor. Por ejemplo, si el emisor es https://auth.example.com , el documento de descubrimiento debe estar disponible en https://auth.example.com/.well-known/openid-configuration .

Una vez que tenga la información anterior, habilite OpenID Connect como proveedor de inicio de sesión para su proyecto de Firebase:

  1. Agrega Firebase a tu proyecto de iOS .

  2. Si no has actualizado a Firebase Authentication con Identity Platform, hazlo. La autenticación OpenID Connect solo está disponible en proyectos actualizados.

  3. En la página Proveedores de inicio de sesión de Firebase console, haga clic en Agregar nuevo proveedor y luego haga clic en OpenID Connect .

  4. Seleccione si utilizará el flujo de código de autorización o el flujo de concesión implícito .

    Debe utilizar siempre el flujo de código si su proveedor lo admite . El flujo implícito es menos seguro y se desaconseja su uso.

  5. Dé un nombre a este proveedor. Tenga en cuenta el ID del proveedor que se genera: algo así como oidc.example-provider . Necesitará esta identificación cuando agregue el código de inicio de sesión a su aplicación.

  6. Especifique su ID de cliente y secreto de cliente, y la cadena del emisor de su proveedor. Estos valores deben coincidir exactamente con los valores que le asignó su proveedor.

  7. Guarde sus cambios.

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

La forma más sencilla de autenticar a sus usuarios con Firebase utilizando su proveedor OIDC es manejar todo 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 que obtuvo en Firebase console.

    Rápido

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

    C objetivo

    FIROAuthProvider *provider = [FIROAuthProvider providerWithProviderID:@"oidc.example-provider"];
    
  3. Opcional : especifique parámetros OAuth personalizados adicionales que desee enviar con la solicitud OAuth.

    Rápido

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

    C objetivo

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

    Consulte con su proveedor los parámetros que admite. Ten en cuenta que no puedes pasar los parámetros requeridos por Firebase con setCustomParameters . Estos parámetros son client_id , response_type , redirect_uri , state , scope y response_mode .

  4. Opcional : especifique alcances de OAuth 2.0 adicionales más allá del perfil básico que desea solicitar al proveedor de autenticación.

    Rápido

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

    C objetivo

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

    Consulte con su proveedor los ámbitos que admite.

  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 .

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

    Rápido

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

    C objetivo

    // 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. 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 OIDC a un usuario existente mediante linkWithCredential . Por ejemplo, puede vincular varios proveedores al mismo usuario, permitiéndoles iniciar sesión con cualquiera de ellos.

    Rápido

    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
    }
    

    C objetivo

    [[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. Se puede usar el mismo patrón con reauthenticateWithCredential , que se puede usar para recuperar credenciales nuevas para operaciones confidenciales que requieren un inicio de sesión reciente.

    Rápido

    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
    }
    

    C objetivo

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

Manejar el flujo de inicio de sesión manualmente

Si ya implementaste el flujo de inicio de sesión de OpenID Connect en tu aplicación, puedes usar el token de ID directamente para autenticarte con Firebase:

Rápido

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
}

C objetivo

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

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

Rápido

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

C objetivo

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 .