Tutorial: Incorporación del registro en una aplicación iOS/macOS mediante la autenticación nativa

Se aplica a: Círculo verde con un símbolo de marca de verificación blanca que indica que el siguiente contenido se aplica a los inquilinos externos. Inquilinos externos (más información)

En este tutorial se muestra cómo registrar a un usuario mediante el código de acceso de un solo uso de correo electrónico o el nombre de usuario (correo electrónico) y la contraseña en la aplicación iOS/macOS mediante la autenticación nativa. También aprenderá a recopilar atributos de usuario durante el registro, incluido un nombre de usuario (alias) y controlar los errores.

En este tutorial, usted hará lo siguiente:

  • Registre un usuario mediante el código de acceso de un solo uso de correo electrónico o el nombre de usuario (correo electrónico) y la contraseña.
  • Recopile atributos de usuario durante el registro, incluido un nombre de usuario (alias).
  • Control de errores de registro.

Prerrequisitos

Registro de un usuario

Para registrar a un usuario mediante el código de acceso de un solo uso de correo electrónico o el nombre de usuario (correo electrónico) y la contraseña, recopila un correo electrónico del usuario y, a continuación, envía un correo electrónico que contiene un código de acceso de un solo uso al usuario. El usuario escribe un código de acceso de un solo uso de correo electrónico válido para validar su nombre de usuario.

Para registrar un usuario, debe hacer lo siguiente:

  1. Cree una interfaz de usuario (UI) para:

    • Recopilar un correo electrónico del usuario. Agregar validación a las entradas para asegurarse de que el usuario escribe una dirección de correo electrónico válida.
    • Recopilar una contraseña si se registra con el nombre de usuario (correo electrónico) y la contraseña.
    • Recopile un nombre de usuario (alias) si la aplicación admite el inicio de sesión basado en alias.
    • Recopilar una contraseña de un solo uso por correo electrónico del usuario.
    • Si es necesario, recopile atributos de usuario.
    • Vuelva a enviar el código de acceso de un solo uso si el usuario no lo recibe.
    • Inicie el flujo de registro.
  2. En la aplicación, agregue un botón, cuyo evento de selección desencadene el siguiente fragmento de código:

    @IBAction func signUpPressed(_: Any) {
        guard let email = emailTextField.text else {
            resultTextView.text = "Email or password not set"
            return
        }
    
        let parameters = MSALNativeAuthSignUpParameters(username: email)
        nativeAuth.signUp(parameters: parameters, delegate: self)
    }
    
    • Para registrar a un usuario mediante el código de acceso de un solo uso por correo electrónico, use el método signUp(parameters:delegate) de la biblioteca, que responde de forma asíncrona llamando a uno de los métodos del objeto delegado proporcionado, que debe implementar el protocolo SignUpStartDelegate. La siguiente línea de código inicia el proceso de registro del usuario:

      nativeAuth.signUp(parameters: parameters, delegate: self)
      

      En el método signUp(parameters:delegate), pase una instancia de MSALNativeAuthSignUpParameters que contenga la dirección de correo electrónico del usuario del formulario de envío, junto con el delegado (una clase que implementa el protocolo SignUpStartDelegate).

    • Para registrar a un usuario mediante correo electrónico con contraseña, use los siguientes fragmentos de código:

      @IBAction func signUpPressed(_: Any) {
          guard let email = emailTextField.text, let password = passwordTextField.text else {
             resultTextView.text = "Email or password not set"
             return
          }
      
          let parameters = MSALNativeAuthSignUpParameters(username: email)
          parameters.password = password
          nativeAuth.signUp(parameters: parameters, delegate: self)
      }
      

      El método signUp(parameters:delegate) de la biblioteca responde de forma asíncrona llamando a uno de los métodos del objeto delegado proporcionado, que debe implementar el protocolo SignUpStartDelegate. La siguiente línea de código inicia el proceso de registro del usuario:

      nativeAuth.signUp(parameters: parameters, delegate: self)
      

      En el signUp(parameters:delegate) método , pase una MSALNativeAuthSignUpParameters instancia que contenga la dirección de correo electrónico del usuario y su contraseña junto con el delegado (una clase que implementa el SignUpStartDelegate protocolo).

    • Para implementar el SignUpStartDelegate protocolo como una extensión para la clase, use:

      extension ViewController: SignUpStartDelegate {
          func onSignUpStartError(error: MSAL.SignUpStartError) {
              resultTextView.text = "Error signing up: \(error.errorDescription ?? "no description")"
          }
      
          func onSignUpCodeRequired(
              newState: MSAL.SignUpCodeRequiredState,
              sentTo: String,
              channelTargetType: MSAL.MSALNativeAuthChannelType,
              codeLength: Int
          ) {
              resultTextView.text = "Verification code sent to \(sentTo)"
          }
      }
      

      La llamada signUp(parameters:delegate) da como resultado una llamada a métodos delegados onSignUpCodeRequired() o onSignUpStartError(). Se llama a onSignUpCodeRequired(newState:sentTo:channelTargetType:codeLength) para indicar que se ha enviado un código para comprobar la dirección de correo electrónico del usuario. Junto con algunos detalles de dónde se ha enviado el código y cuántos dígitos contiene, este método delegado también tiene un newState parámetro de tipo SignUpCodeRequiredState, que proporciona acceso a dos métodos nuevos:

      • submitCode(code:delegate)
      • resendCode(delegate)

      Para enviar el código proporcionado por el usuario, use:

      newState.submitCode(code: userSuppliedCode, delegate: self)
      
      • Para implementar el SignUpVerifyCodeDelegate protocolo como una extensión para la clase, use:

        extension ViewController: SignUpVerifyCodeDelegate {
            func onSignUpVerifyCodeError(error: MSAL.VerifyCodeError, newState: MSAL.SignUpCodeRequiredState?) {
                resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")"
            }
        
            func onSignUpCompleted(newState: SignInAfterSignUpState) {
                resultTextView.text = "Signed up successfully!"
            }
        }
        

        submitCode(code:delegate) acepta un parámetro delegado y debe implementar los métodos necesarios en el SignUpVerifyCodeDelegate protocolo. En el escenario más común, recibe una llamada a onSignUpCompleted(newState) que indica que el usuario ha sido registrado y que el flujo se ha completado.

Recopilación de atributos de usuario durante el registro

Tanto si se registra un usuario mediante el código de acceso de un solo uso de correo electrónico o un nombre de usuario (correo electrónico) y una contraseña, puede recopilar atributos de usuario antes de crear la cuenta de un usuario. Se puede llamar al método signUp(parameters:delegate) usando un MSALNativeAuthSignUpParameters que tiene una propiedad de atributos.

  1. Para recopilar atributos de usuario, use el siguiente fragmento de código:

    let attributes = [
        "country": "United States",
        "city": "Redmond"
    ]
    
    let parameters = MSALNativeAuthSignUpParameters(username: email)
    parameters.password = password
    parameters.attributes = attributes
    nativeAuth.signUp(parameters: parameters, delegate: self)
    

    El signUp(parameters:delegate)da como resultado una llamada a métodos delegados onSignUpCodeRequired() o onSignUpStartError(), o en una llamada a onSignUpAttributesInvalid(attributeNames: [String]) si se implementa en el delegado.

  2. Para implementar el SignUpStartDelegate protocolo como una extensión para la clase, use el siguiente fragmento de código:

    extension ViewController: SignUpStartDelegate {
        func onSignUpStartError(error: MSAL.SignUpStartError) {
            resultTextView.text = "Error signing up: \(error.errorDescription ?? "no description")"
        }
    
        func onSignUpCodeRequired(
            newState: MSAL.SignUpCodeRequiredState,
            sentTo: String,
            channelTargetType: MSAL.MSALNativeAuthChannelType,
            codeLength: Int
        ) {
            resultTextView.text = "Verification code sent to \(sentTo)"
        }
    
        func onSignUpAttributesInvalid(attributeNames: [String]) {
           resultTextView.text = "Invalid attributes  \(attributeNames)"
        }
    }
    

    Si los atributos no son válidos, se llama al método onSignUpAttributesInvalid(attributeNames: [String]). En este caso, muestre la lista de atributos no válidos para el usuario. En caso contrario, se llama de onSignUpCodeRequired(newState:sentTo:channelTargetType:codeLength) para indicar que se ha enviado un código para verificar la dirección de correo electrónico del usuario. Aparte de los detalles, como el destinatario del código y el número de dígitos del código, este método delegado tiene un newState parámetro de tipo SignUpCodeRequiredState, que proporciona acceso a dos métodos nuevos:

    • submitCode(code:delegate)
    • resendCode(delegate)

Atributos de usuario en una o varias páginas

Para distribuir los atributos entre una o varias páginas, establezca como obligatorios en la configuración de la instancia de gestión de identidades y accesos de clientes (CIAM) los atributos que desee recopilar en distintas páginas.

Llame a signUp(parameters:delegate) sin pasar ningún atributo a la instancia MSALNativeAuthSignUpParameters. El siguiente paso es llamar newState.submitCode(code: userSuppliedCode, delegate: self) a para comprobar el correo electrónico del usuario.

Implemente el SignUpVerifyCodeDelegate protocolo como una extensión para la clase como antes, pero esta vez debe implementar el método onSignUpAttributesRequired(attributes:newState) opcional además de los métodos necesarios:

extension ViewController: SignUpVerifyCodeDelegate {
    func onSignUpAttributesRequired(newState: SignUpAttributesRequiredState) {
        resultTextView.text = "Attributes required"
    }

    func onSignUpVerifyCodeError(error: MSAL.VerifyCodeError, newState: MSAL.SignUpCodeRequiredState?) {
        resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")"
    }

    func onSignUpCompleted(newState: SignInAfterSignUpState) {
        resultTextView.text = "Signed up successfully!"
    }
}

Este método delegado tiene un newState parámetro de tipo SignUpAttributesRequiredState, que proporciona acceso a un nuevo método:

  • submitAttributes(attributes:delegate)

Para enviar los atributos proporcionados por el usuario, use el siguiente fragmento de código:

let attributes = [
    "country": "United States",
    "city": "Redmond"
]

newState.submitAttributes(attributes: attributes, delegate: self)

Implemente también el SignUpAttributesRequiredDelegate protocolo como una extensión para la clase :

extension ViewController: SignUpAttributesRequiredDelegate {
    func onSignUpAttributesRequiredError(error: AttributesRequiredError) {
        resultTextView.text = "Error submitting attributes: \(error.errorDescription ?? "no description")"
    }

    func onSignUpAttributesRequired(attributes: [MSALNativeAuthRequiredAttribute], newState: SignUpAttributesRequiredState) {
        resultTextView.text = "Attributes required"
    }

    func onSignUpAttributesInvalid(attributeNames: [String], newState: SignUpAttributesRequiredState) {
        resultTextView.text = "Attributes invalid"
    }

    func onSignUpCompleted(newState: SignInAfterSignUpState) {
        resultTextView.text = "Signed up successfully!"
    }
}

Cuando el usuario no proporciona todos los atributos necesarios o los atributos no son válidos, se llama a estos métodos delegados:

  • onSignUpAttributesInvalid: indica que uno o varios atributos enviados no han superado la validación de entrada. Este error contiene un parámetro attributeNames, que es una lista de todos los atributos enviados por el desarrollador que no superaron la validación de entrada.
  • onSignUpAttributesRequired: indica que el servidor requiere el envío de uno o más atributos antes de poder crear la cuenta de usuario. Esto sucede cuando uno o varios atributos se establecen como obligatorios en la configuración del inquilino. Este resultado contiene el parámetro attributes, que es una lista de objetos MSALNativeAuthRequiredAttribute, que describe los detalles sobre los atributos de usuario que requiere la API.

Ambos métodos delegados contienen una nueva referencia de estado. Use el newState parámetro para llamar submitAttributes(attributes:delegate) de nuevo con los nuevos atributos.

Recopilar un nombre de usuario (alias) durante el registro

El nombre de usuario (alias) es un atributo de usuario especial. Al igual que otros atributos, como la ciudad o el país, se recopila al registrarse. A diferencia de esos atributos, el usuario puede usar posteriormente el alias para iniciar sesión. El alias (por ejemplo, "johndoe") proporciona a los usuarios una manera más corta y fácil de iniciar sesión que su dirección de correo electrónico.

El nombre de usuario (alias) no reemplaza el nombre de usuario (correo electrónico). Durante el registro, la aplicación siempre debe recopilar el nombre de usuario (correo electrónico) como identificador principal y recopila el alias como atributo junto con el correo electrónico. Al iniciar sesión, el usuario puede elegir iniciar sesión con su nombre de usuario (correo electrónico) o con su nombre de usuario (alias).

Cuando el atributo de usuario integrado Username está habilitado en el flujo de usuario de registro, el SDK lo acepta a través del mismo diccionario de atributos que se usa para otros atributos, como clave flatusername . Puede pasar el nombre de usuario (alias) directamente en la signUp llamada para que el usuario no tenga que pasar por un paso independiente requerido por atributos.

Para recopilar un nombre de usuario (alias), agregue un campo de entrada para el nombre de usuario en la interfaz de usuario de registro junto con el campo de correo electrónico y, a continuación, pase el alias como atributo en la llamada de registro:

guard let email = emailTextField.text, !email.isEmpty,
      let password = passwordTextField.text, !password.isEmpty,
      let username = usernameTextField.text, !username.isEmpty else {
    showResultText("Please fill in all fields")
    return
}

let attributes: [String: Any] = [
    "flatusername": username
]

let parameters = MSALNativeAuthSignUpParameters(username: email)
parameters.password = password
parameters.attributes = attributes
nativeAuth.signUp(parameters: parameters, delegate: self)

Para los flujos de código de acceso de un solo uso (sin contraseña) de correo electrónico, pase los atributos sin establecer una contraseña:

let parameters = MSALNativeAuthSignUpParameters(username: email)
parameters.attributes = attributes
nativeAuth.signUp(parameters: parameters, delegate: self)

Al gestionar los errores del registro con nombre de usuario (alias), la propiedad error.isUserAlreadyExists también cubre un alias duplicado, y error.isInvalidAttributes indica un valor de alias no válido.

Manejo de errores de inscripción

Durante el registro, no todas las acciones se realizan correctamente. Por ejemplo, el usuario podría intentar registrarse con una dirección de correo electrónico que ya está en uso o enviar un código no válido.

En la implementación anterior del SignUpStartDelegate protocolo, el error se mostraba simplemente al controlar la onSignUpStartError(error) función de delegado.

Para mejorar la experiencia del usuario mediante la administración del tipo de error concreto, use el siguiente fragmento de código:

func onSignUpStartError(error: MSAL.SignUpStartError) {
    if error.isUserAlreadyExists {
        resultTextView.text = "Unable to sign up: User already exists"
    } else if error.isInvalidPassword {
        resultTextView.text = "Unable to sign up: The password is invalid"
    } else if error.isInvalidUsername {
        resultTextView.text = "Unable to sign up: The username is invalid"
    } else {
        resultTextView.text = "Unexpected error signing up: \(error.errorDescription ?? "no description")"
    }
}

Opcional: Iniciar sesión después de un flujo de registro

Después de un flujo de registro correcto, puede iniciar sesión de un usuario sin iniciar un flujo de inicio de sesión. Si el usuario se registró con un nombre de usuario (alias), puede iniciar sesión mediante su dirección de correo electrónico o su alias. Obtén más información en el artículo Tutorial: Inicio de sesión del usuario automáticamente después de registrarse en una aplicación de iOS/macOS.

Paso siguiente