https://d226lax1qjow5r.cloudfront.net/blog/blogposts/add-two-factor-authentication-to-swift-ios-apps-dr/nexmo-2fa_ios_swift.jpg

Añadir 2FA a aplicaciones iOS con Swift y Verify API de Nexmo

Publicado el May 12, 2021

Tiempo de lectura: 4 minutos

Autenticación de dos factores (2FA) añade una capa adicional de seguridad para los usuarios que acceden a información sensible.

Aunque hay múltiples modos de autenticarse con algo que sabes, eres o tienes, nos centraremos exclusivamente en el último. En este tutorial, cubriremos cómo implementar la autenticación de dos factores para el número de teléfono de un usuario con los puntos finales de Verify API de Nexmo.

Después de leer la entrada del blog sobre cómo configurar un servidor para utilizar Nexmo Verify ya está listo para configurar una aplicación iOS para conectarse en red con el servidor.

La aplicación tendrá que hacer algunas cosas. Almacenar un request_id como responseId para poder cancelar o completar una solicitud de verificación. Así como hacer una llamada de red a tres puntos finales:

  • Inicie una verificación.

  • Compruebe un código de verificación.

  • Cancelar una solicitud de verificación.

Configuración de Nexmo

Después de leer la entrada del blog sobre cómo configurar un servidor para utilizar Nexmo Verify ya está listo para configurar una aplicación iOS para conectarse en red con el servidor.

Configuración del entorno

  1. Descargue el proyecto de inicio, una aplicación de vista única:

    git clone https://github.com/nexmo-community/verify-ios-demo/

  2. Añada un archivo CocoaPods a su directorio raíz, e instale el pod después de modificar su podfile para incluir lo siguiente:

pod 'Alamofire'
  1. Asegúrese de tener a mano un iPhone con tarjeta SIM.

  2. Para configurar correctamente el entorno necesitamos simular un servidor como en la aplicación de servidor de Glitch. Para configurarlo, vamos al archivo .env y establecemos los valores necesarios para API_KEY & API_SECRET

Revisar la interfaz de usuario

Con la configuración fuera del camino vamos a revisar la interfaz de usuario para la verificación y confirmación.

  1. Un archivo CocoaTouch llamado VerificationViewController que es una subclase de UIViewController; esta clase se asigna a una escena en Main.storyboard para que tome VerificationViewController como su clase personalizada.

  2. Tres TextField en VerificationViewController, salidas llamadas inputEmailAddress, inputPassword, inputTelephoneNumber respectivamente.

  3. Un botón en VerificationViewController llamado loginBtn.

  4. Un botón en VerificationViewControlleruna acción llamada cancelVerification.

  5. Un segue llamado authenticateWith2FACodeque conecta VerificationViewController a ConfirmationViewController.

  6. Un archivo CocoaTouch llamado ConfirmationViewController que es una subclase de UIViewController; asignado a una escena en Main.storyboard para que tome ConfirmationViewController como su clase personalizada.

  7. A TextField, ConfirmationViewController, inputEmailAddress.

  8. Un botón en VerificationViewControlleruna acción llamada cancelVerification.

Nota: Puede establecer las restricciones de los campos de texto, botones o etiquetas como desee.

Configuración del servidor Glitch

Desglosemos lo que nos espera. La API de Nexmo para la verificación consiste esencialmente en dos enlaces. El primero es https://api.nexmo.com/verify/json. Este enlace verifica el número de teléfono del usuario. El segundo enlace es https://api.nexmo.com/verify/check/json. Este enlace verifica que el usuario está en posesión del dispositivo mediante el envío de un SMS con un PIN.

En este tutorial, sin embargo, no nos dirigimos directamente a ninguno de estos puntos finales de la API. Utilizamos un SDK llamado Alamofire para comunicarnos a través de un servidor Glitch intermediario.

Pasos para configurar el servidor

El primer paso para configurar el servidor Glitch es remezclar el servidor Glitch para su propio despliegue. En el sitio hay un botón de remezcla.

Programación de la interfaz de usuario

Con el servidor Glitch configurado, el siguiente paso es programar la interfaz de usuario de la aplicación para que solicite o responda a solicitudes con el servidor.

  1. En la parte superior de VerificationViewController incluya la línea import Alamofire.

  2. Dentro del ámbito de la declaración de clase VerificationViewControllerañada la línea var responseId = String(). Estamos inicializando una cadena vacía en la que mantendremos una referencia a nuestra clase responseId.

Nota: Es posible que desee utilizar NSUserDefaults o una de las muchas clases diferentes para el almacenamiento local. Dado que es una cuestión de preferencia, le dejamos a usted como desarrollador decidir cómo almacenar los archivos responseId.

  1. En el @IBAction para verifyTelephoneNumber añade la siguiente línea: self.verifyViaAPI(), que es una función que programaremos para golpear el primer enlace.

  2. Cree una función llamada verifyViaAPI() con el siguiente código:

func requestVerificationWithAPI() {
        //Sending SMS
        let param = ["telephoneNumber": telephoneTextField.text]

        Alamofire.request("https://nexmo-verify.glitch.me/request", parameters: param as Any).responseJSON { response in

            print("--- Sent SMS API ----")
            print("Response: \(response)")

            if let json = response.result.value as? [String:AnyObject] {

                self.responseId = json["request_id"] as! String
                self.performSegue(withIdentifier: "authenticateWith2FA", sender: self)
            }
        }
    }

Cuando se envía la solicitud de verificación, nuestro siguiente paso es pasar de un controlador de vista al siguiente. Durante la transición, pasaremos nuestro responseId para que nuestro servidor Glitch sepa con qué aplicación está tratando. He aquí cómo programar prepare(for:sender:):

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  let confirmationVC = segue.destination as! ConfirmationViewController
  confirmationVC.responseId = responseId
}

A medida que pasamos el responseId de un controlador de vista al siguiente, aterrizamos en el controlador de vista ConfirmationViewController donde confirmamos si el usuario que solicita la autenticación tiene el dispositivo asociado a su número.

Segundo enlace : SMS

  1. En el @IBAction para verifyPin añada la línea self.verifyPinViaAPI()que es una función que programaremos para golpear el segundo enlace.

  2. Cree una función llamada verifyPinViaAPI() con el siguiente código:

func verifyPinViaAPI() {

        guard let requestId = requestId,
                let code = codeTextField.text else { return }

        let url = "https://nexmo-verify.glitch.me/check"
        let parameters = ["request_id": requestId,
                          "code": code]

        guard let request = URLRequestManager.getRequest(url, parameters: parameters) else { return }

        Alamofire.request(request).responseJSON { [weak self] response in

            print("--- Verify SMS API ----")
            print("Response: \(response)")

            if let json = response.result.value as? [String:AnyObject],
                let status = json["status"] as? String {

                // if status is zero, then success; if not something
                // went wrong
                if Int(status) == 0 {
                    DispatchQueue.main.async {
                        self?.dismiss(animated: true)

                    }
                }
            }
        }
    }

El código es similar al de la primera solicitud. En este fragmento de código, analizamos la respuesta para comprobar si la verificación se ha realizado correctamente. Si el estado devuelto en la respuesta es cero, el usuario está autenticado. En caso contrario, el usuario debe empezar de nuevo.

Anulación

Por último, pero no por ello menos importante, está la cancelación. La cancelación se programa de forma similar:

func cancelRequest() {

        guard let requestId = requestId else { return }

        let parameters = ["request_id": requestId]
        let url = "https://nexmo-verify.glitch.me/cancel"

        guard let request = URLRequestManager.getRequest(url, parameters: parameters) else { return }

        Alamofire.request(request).responseJSON { response in

            print("--- Cancel Request API ----")
            print("Response: \(response)")

            if let json = response.result.value as? [String:AnyObject],
                let status = json["status"] as? String {

                if Int(status) == 0 {
                    print("Request Cancelled Successfully")
                }
            }
        }
    }

¿Qué se ha conseguido y aprendido?

Ahora tiene un número verificado y ha comprobado dos veces que su usuario está en posesión del número del dispositivo, ¡y todo esto lo ha hecho con la API de Nexmo!

Con esta implementación, sólo se sabe desde el lado del cliente que el número está verificado. En una aplicación del mundo real, necesitarías decirle a tu backend que el número está verificado. Podrías lograrlo de dos maneras, llamando a esa actualización en el flujo de éxito desde el cliente o desde tus propias retrollamadas.

Si desea ver el producto final, puede descargar el proyecto terminado aquí.

¿Y ahora qué?

Si lo desea, puede implementar el resto de los puntos finales en la Verify API. Tenga en cuenta que esto requerirá que añada más puntos finales en el servidor proxy de la API.

También puede añadir puntos finales adicionales para cubrir la Number Insight API. Esto también requerirá que añada más puntos finales en el servidor proxy de API.

También hay una versión para Android de este artículo. Lee más de nuestro defensor de los desarrolladores Chris Guzman.

Compartir:

https://a.storyblok.com/f/270183/190x205/22a0a799fa/eric_giannini.png
Eric GianniniAntiguos alumnos de Vonage

Eric Giannini era el defensor de los desarrolladores iOS en Nexmo. Es un apasionado tanto de Objective-C como de Swift, especialmente de este último. Eric bloguea a menudo sobre esto, aquello o lo otro de iOS, hackeando aplicaciones, construyendo SDKs, o prototipando rápidamente. También se reúne con desarrolladores de iOS u otros tipos de Swift fuertemente tipados en conferencias, Meetups y otras funciones variadas.