Compartir vía


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. iOS (Swift) Círculo verde con un símbolo de marca de verificación blanca. macOS (Swift)

En este tutorial se muestra cómo registrar 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, y cómo recopilar los atributos del usuario en la aplicación móvil iOS/macOS mediante la autenticación nativa.

  • 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.
  • Recopilación de atributos de usuario durante el registro.
  • Control de errores de registro.

Requisitos previos

Registro de un usuario

Para registrar 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 un correo electrónico del usuario y envíe un correo electrónico que contenga 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.
    • Recopilar un código de acceso de un solo uso de 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
        }
    
        nativeAuth.signUp(username: email, delegate: self)
    }
    
    • Para registrar a un usuario mediante el código de acceso de un solo uso de correo electrónico, usamos el método signUp(username:delegate) de la biblioteca, que responde de forma asincrónica llamando a uno de los métodos del objeto delegado pasado, que debe implementar el protocolo SignUpStartDelegate. La siguiente línea de código inicia el proceso de registro del usuario:

      nativeAuth.signUp(username: email, delegate: self)
      

      En el método signUp(username:delegate), pasamos la dirección de correo electrónico del usuario desde el formulario de envío y 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
          }
      
          nativeAuth.signUp(username: email,password: password,delegate: self)
      }
      

      Usamos el método signUp(username:password:delegate) de la biblioteca, que responde de forma asincrónica llamando a uno de los métodos del objeto delegado pasado, que debe implementar el protocolo SignUpStartDelegate. La siguiente línea de código inicia el proceso de registro del usuario:

      nativeAuth.signUp(username: email, password: password, delegate: self)
      

      En el método signUp(username:password:delegate), pasamos la dirección de correo electrónico del usuario, su contraseña y el delegado (una clase que implementa el protocolo SignUpStartDelegate).

    • Para implementar el protocolo SignUpStartDelegate como una extensión para nuestra 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 a signUp(username:password:delegate) o signUp(username: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 parámetro newState de tipo SignUpCodeRequiredState, que nos da acceso a dos nuevos métodos:

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

      Para enviar el código con el que el usuario nos proporcionó, use:

      newState.submitCode(code: userSuppliedCode, delegate: self)
      
      • Para implementar el protocolo SignUpVerifyCodeDelegate como una extensión para nuestra 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 debemos implementar los métodos necesarios en el protocolo SignUpVerifyCodeDelegate. En el escenario más común, recibiremos una llamada a onSignUpCompleted(newState) que indica que el usuario se ha 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. El método signUp(username:attributes:delegate) acepta atributos como parámetro.

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

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

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

  2. Para implementar el protocolo de SignUpStartDelegate como una extensión de nuestra 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, se muestra 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 detalles como el destinatario del código y el número de dígitos del código, este método delegado tiene un parámetro newState de tipo SignUpCodeRequiredState, que nos da acceso a dos nuevos métodos:

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

Atributos de usuario en una o varias páginas

Para distribuir los atributos en una o varias páginas, debemos establecer los atributos que pretendemos recopilar en distintas páginas como obligatorios en la configuración del inquilino de la administración de identidad y acceso de clientes (CIAM).

Llamamos a signUp(username:password:delegate) sin pasar ningún atributo. El siguiente paso será llamar a newState.submitCode(code: userSuppliedCode, delegate: self) para comprobar el correo electrónico del usuario.

Implementamos el protocolo SignUpVerifyCodeDelegate como una extensión para nuestra clase como antes, pero esta vez debemos implementar el método opcional onSignUpAttributesRequired(attributes:newState) 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 parámetro newState de tipo SignUpAttributesRequiredState, que nos proporciona acceso a un nuevo método:

  • submitAttributes(attributes:delegate)

Para enviar los atributos que el usuario nos proporcionó, use el siguiente fragmento de código:

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

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

También implementaremos el protocolo SignUpAttributesRequiredDelegate como una extensión para nuestra 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. Usaremos el parámetro newState para llamar a submitAttributes(attributes:delegate) de nuevo con los nuevos atributos.

Control de errores de registro

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 protocolo SignUpStartDelegate, simplemente se muestra el error al controlar la función de delegado onSignUpStartError(error).

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