https://d226lax1qjow5r.cloudfront.net/blog/blogposts/adding-phone-sms-tts-biometric-verification-ios-application-dr/Screen-Shot-2016-12-03-at-11.50.47-AM.png

Ajouter la vérification téléphonique et biométrique à votre application iOS

Publié le May 17, 2021

Temps de lecture : 10 minutes

L'authentification à deux facteurs L'authentification à deux facteurs (2FA) ajoute une couche supplémentaire de sécurité pour les utilisateurs qui accèdent à des informations sensibles. Il existe plusieurs types d'authentification à deux facteurs :

  • Quelque chose que vous connaissez (nom d'utilisateur, mot de passe)

  • Quelque chose que vous avez (votre téléphone/SIM)

  • Ce que vous êtes (empreinte digitale biométrique ou scan de la rétine)

Dans ce tutoriel, nous verrons comment vous pouvez ajouter ces trois éléments à une application iOS à l'aide du Nexmo Verify SDK.

Vonage API Account

To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.

This tutorial also uses a virtual phone number. To purchase one, go to Numbers > Buy Numbers and search for one that meets your needs.

Pour commencer

L'utilisation du SDK vous permettra d'ajouter une couche de sécurité supplémentaire. Vous vous assurerez que l'utilisateur est lié à un appareil physique spécifique en capturant l'identifiant de l'appareil et un code PIN SMS/TTS. Le fait de certifier que l'utilisateur se connecte à partir du même appareil que lors de la tentative de connexion précédente permet de réduire les spams et les fraudes.

Nous utiliserons une application de démarrage (Swift 3) qui utilise une application de type Back4App pour la connexion de l'utilisateur (quelque chose que vous connaissez). Nous utiliserons le SDK Verify pour notre solution 2FA par SMS et TTS, et Touch ID d'Apple pour la vérification biométrique (quelque chose que vous êtes).

Configurez votre base de données Back{4}App

Back{4}App est un backend qui vous permet de créer et d'héberger des applications Parse (ce qui est pratique depuis que Parse a fermé). Si vous n'avez pas de compte Back{4}App, inscrivez-vous et créez une application.

Creating a new app in Back{4}App

Une fois votre application créée, cliquez sur le bouton "serveur" dans la section "Core Settings". Vous serez alors dirigé vers une page contenant vos nouveaux identifiants d'application. Une fois que vous avez pris note de votre ID d'application et de votre clé client, cliquez sur le bouton "Retour" et allez au "Tableau de bord" situé dans la section "Paramètres de base". Une fois que vous êtes redirigé vers le tableau de bord, dirigez-vous vers la section "Core", cliquez sur "Edit" (situé dans le coin supérieur droit) et ajoutez les colonnes suivantes à la classe "User" :

  • "vérification" (Numbers)

  • 'épargne (Nombre)

  • 'sitekey' (Fichier - image pour les utilisateurs)

  • numéro de téléphone (chaîne)

  • smsVerification" (valeur booléenne - permet aux utilisateurs d'activer la vérification par SMS lors de la connexion)

Adding a new column to the 'User' class

Maintenant que Back{4} apps est mis en place, nous pouvons commencer à mettre en place notre application de démarrage.

Obtenir l'application de démarrage

Commençons par récupérer l'application de démarrage sur GitHub. Dans votre Terminal, exécutez ce qui suit :

git clone https://github.com/nexmo-community/nexmo-verify-2fa-ios-example.git -b getting-started cd nexmo-verify-2fa-ios-example

Le repo comporte une branche "get-started" (pre-2FA), qui vous permet de suivre le tutoriel ci-dessous, et une branche "master", qui contient la version finale de ce tutoriel.

Ouvrez le NexmoBankingApp.xcproj dans XCode. Sélectionnez "NexmoBankingApp" pour ouvrir les paramètres de votre application, et mettez à jour le "Bundle Identifier" du projet avec un identifiant valide et un nom d'application enregistré sur le portail des développeurs d'Apple. Ajoutez votre identifiant d'application Back4App et votre clé client dans AppDelegate.swift.

let configuration = ParseClientConfiguration {
$0.applicationId = "BACK4APP_APP_ID"
$0.clientKey = "BACK4APP_CLIENT_KEY"
$0.server = "https://parseapi.back4app.com"
}
Parse.initializeWithConfiguration(configuration)

Une fois que vous êtes entré, allez dans "ViewController.swift" et ajoutez un utilisateur fictif à la base de données en décommentant l'appel à la fonction "signUpDemoAccount()" dans la méthode "viewDidLoad()" dans "ViewController.swift" :

override func viewDidLoad() {
super.viewDidLoad()
self.onlineID.delegate = self
signUpDemoAccount() //Uncomment to create dummy user
}

Mettez à jour les champs nom d'utilisateur, mot de passe, email et numéro de téléphone du PFUser dans la fonction 'signUpDemoAccount()'.

func signUpDemoAccount() {
var user = PFUser()
user.username = "ENTERUSERNAME"
user.password = "ENTERPASSWORD"
user.email = "ENTEREMAILADDRESS@DEMO.NET"
user["phoneNumber"] = "ENTER-YOUR-PHONE-HERE"
user["smsVerification"] = false
user["checking"] = 5000
user["saving"] = 10000
let sitekeyImage = UIImage(named: "nexmo.png")
let imageData = UIImagePNGRepresentation(sitekeyImage!)
let imageFile = PFFile(name:"nexmo.png", data:imageData!)
user["sitekey"] = imageFile
user.signUpInBackground {
(success, error) -> Void in
if !success {
print(error.debugDescription)
} else {
print("User signed up.")
}
}
}

Lancez l'application. Le PFUser sera créé et remplira le tableau de bord de Back4App. Pour éviter de créer un autre utilisateur lorsque vous relancez l'application, vous devez commenter l'appel à la fonction 'signUpDemoAccount()' dans la méthode 'viewDidLoad()' après avoir lancé l'application la première fois.

User is created and stored in Back{4}Apps

Lancez à nouveau l'application. Vous pourrez accéder aux informations du compte de l'utilisateur en saisissant les identifiants de l'utilisateur nouvellement créé.

Maintenant, renforçons la sécurité de l'application en ajoutant l'option 2FA.

Configuration de l'application Nexmo

Créez un compte Nexmo et accédez à votre tableau de bord client. Cliquez sur l'onglet Verify et ajoutez une nouvelle application sous "Vos Applications". Configurez votre application avec un nom, une durée d'inactivité d'Instant (durée maximale pendant laquelle l'utilisateur restera vérifié ; dans ce cas, les utilisateurs expireront immédiatement) et la longueur du code PIN.

Add a new Nexmo App in the dashboard

Ensuite, ajoutons le SDK Nexmo Verify. Le SDK Verify peut être facilement ajouté à votre projet en utilisant les Cocoapods. Créez un Podfile dans le répertoire de votre projet, ajoutez le pod 'NexmoVerify' dans le fichier, et installez le pod via Terminal. (Si le pod ne peut pas être trouvé, exécutez pod update pour mettre à jour Cocoapods).

pod init open Podfile
Inside Podfile
# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'
target 'NexmoBankingApp' do
# Comment this line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
# Pods for NexmoBankingApp
pod ‘NexmoVerify’
end
pod install

Une fois l'installation du pod terminée, fermez Xcode et ouvrez le nouveau fichier de projet 'xcworkspace'. Vous êtes maintenant prêt à vous plonger dans le code !

Si vous voulez en savoir plus sur le NexmoVerify vous pouvez consulter le code source sur Github.

Plonger dans le code

Maintenant que vos dépendances sont en place et que vous avez obtenu les identifiants de l'application Nexmo, il est temps de les ajouter à votre fichier 'AppDelegate'.

Dans AppDelegate.swift :

import NexmoVerify //Add to top of the file

fileprivate var appID = "YOUR_NEXMO_APP_ID"
fileprivate var sharedSecret = "YOUR_NEXMO_SHARED_SECRET"

Initialiser le client Nexmo

Initialiser le client Nexmo dans la fonction 'didFinishLaunchingWithOptions' du fichier 'AppDelegate'.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let configuration = ParseClientConfiguration {
$0.applicationId = "BACK4APP_APP_ID"
$0.clientKey = "BACK4APP_CLIENT_KEY"
$0.server = "https://parseapi.back4app.com"
}
Parse.initializeWithConfiguration(configuration)
NexmoClient.start(applicationId: appID, sharedSecretKey: sharedSecret)
return true
}

Ajouter la vérification biométrique au SitekeyViewController

Si la connexion est réussie, parce que nous avons fourni à Back4Apps le nom d'utilisateur et le mot de passe, le deuxième écran emmène l'utilisateur à la vérification de son sitekey où nous ajouterons la vérification biométrique Touch ID.

L'utilisateur appuie sur le bouton d'ouverture de session en utilisant l'API LocalAuthentication d'Apple pour demander une vérification Touch ID. Si l'appareil n'est pas compatible avec Touch ID (pas de lecteur d'empreintes digitales), l'utilisateur ne procède pas à la vérification biométrique. Ajoutez une séquence ("signInStopped") de sorte que lorsque l'utilisateur n'est pas en mesure de passer avec succès la vérification Touch ID, il est déconnecté et renvoyé à la page de connexion. En fonction des préférences de l'utilisateur en matière de vérification par SMS, la fonction de flux de travail continu déclenchera une demande de vérification après le passage à l'écran de vérification du code PIN (que nous créons ensuite) ou l'affichage de la page du compte de l'utilisateur.

import LocalAuthentication

@IBAction func signInButton(_ sender: AnyObject) {
initialWorkFlow()
}
func initialWorkFlow() {
let context = LAContext()
var error: NSError?
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
let reason = "Authenticate with Touch ID"
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason, reply:
{(success, error) in
if success {
self.continueWorkflow()
}
else {
let alert = UIAlertController(title: "Failed Identification", message: "Touch ID Authentication Failed. Sign In process stopped.", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "Continue", style: .default) {
UIAlertAction in
PFUser.logOut()
self.performSegue(withIdentifier: "signInStopped", sender: self)
}

alert.addAction(defaultAction)
self.present(alert, animated: true, completion: nil)
}
})
}
else {
print("Touch ID not available")
self.continueWorkflow()
}
}
func continueWorkflow() {
if (PFUser.current()?["smsVerification"] as! Bool) {
self.performSegue(withIdentifier: "verifyPin", sender: self)
}
else {
self.performSegue(withIdentifier: "showAccount", sender: self)
}
}

Touch ID requested

Ajouter un contrôleur de vue pour la vérification et ajouter la logique 2FA à la VC

Ajoutez un nouveau fichier à votre projet ('VerifyPinViewController') et créez un contrôleur de vue dans le Storyboard à l'aide de l'Interface Builder. Ouvrez le menu 'Utilities' en cliquant sur le bouton en haut à droite de l'Interface Builder. Cliquez sur le bouton "Identity Inspector" et saisissez le nom de la nouvelle classe après avoir cliqué sur le lien View Controller dans l'IB vers le fichier. Ensuite, ajoutez une zone de texte ("pinCode" - IBOutlet) ainsi qu'un bouton ("verifyPin" - IBAction) pour soumettre le code pin. Créez un lien ("verifyPin") connecté au "SitekeyViewController" et au contrôleur de vue nouvellement créé.

Dans la méthode "viewDidAppear" du contrôleur de vue nouvellement ajouté, appelez la fonction ci-dessous.

import Foundation
import UIKit
import Parse
import NexmoVerify

class VerifyViewController : UIViewController {
@IBOutlet weak var pinCode: UITextField!
@IBAction func verifyButton(_ sender: Any) {
}

override func viewDidLoad() {
super.viewDidLoad()
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
let alert = UIAlertController( title: "User Phone Verification", message: "Your identity is being verified.", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "Continue", style: .default) {
UIAlertAction in
self.verifyUser()
}
alert.addAction(defaultAction)
present(alert, animated: true, completion: nil)
}

Link Class in IB

Récupérez le numéro de téléphone de l'utilisateur dans la base de données de Back4Apps et déclenchez une demande de vérification à l'aide de la méthode getVerifiedUser(). Créer un lien ('pinVerified') qui est connecté de 'VerifyPinController' à 'StatementViewController'.

func verifyUser() {
VerifyClient.getVerifiedUser(countryCode: "US", phoneNumber: PFUser.current()?["phoneNumber"] as! String,
onVerifyInProgress: {
},
onUserVerified: {
self.performSegue(withIdentifier:"pinVerified", sender: self)
},
onError: { verifyError in
switch (verifyError) {
case .invalidPinCode:
UIAlertView(title: "Wrong Pin Code", message: "The pin code you entered is invalid.", delegate: nil, cancelButtonTitle: "Try again!").show()
case .invalidCodeTooManyTimes:
let alert = UIAlertController(title: "Unsucessful Identification", message: "Logging out. Goodbye.", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "Goodbye", style: .default) {
UIAlertAction in

VerifyClient.cancelVerification() { error in
if let error = error {
// something wen't wrong whilst attempting to cancel the current verification request
return
}
}
self.performSegue(withIdentifier: "logout", sender: self)
}
alert.addAction(defaultAction)
self.present(alert, animated: true, completion: nil)
default:
print(verifyError.rawValue)
break
}
})
}

De même, appelez la méthode checkPinCode fournie par le client Nexmo lorsque le bouton est enfoncé pour vérifier le code PIN fourni par l'utilisateur.

@IBAction func verifyButton(sender: AnyObject) {
if pinCode.text!.isEmpty {
let alert = UIAlertController(title: "Enter Pin Code", message: "Please check your phone and enter the pin code send via SMS.", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "Back", style: .default, handler: nil)
alert.addAction(defaultAction)
present(alert, animated: true, completion: nil)
}
else {
VerifyClient.checkPinCode(pinCode.text!)
}
}

Ajouter l'option de vérification par SMS lors de la connexion

Ensuite, ajoutez la logique qui permet à l'utilisateur d'activer la vérification par SMS. Ajoutez un élément d'interface utilisateur switch à votre "StatementViewController" en tant qu'IBOutlet. Ajoutez également une variable booléenne pour contenir la valeur de l'interrupteur. La valeur de l'interrupteur est stockée dans la base de données lors de la déconnexion de l'utilisateur. Si l'interrupteur a été activé, une vérification par SMS sera déclenchée lors de la prochaine connexion. Une fois la vue affichée, vérifiez les valeurs des comptes de chèques et d'épargne pour vous assurer qu'elles ne sont pas nulles.

@IBOutlet weak var switch2FA: UISwitch!
var switchBoolValue:Bool!
func logout() {
if switchBoolValue == true {
let alert = UIAlertController(title: "SMS Verification", message: "Perform SMS verification on login?", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "Continue", style: .default) {
UIAlertAction in
PFUser.current()?["smsVerification"] = true
PFUser.current()?.saveInBackground()
self.performSegue(withIdentifier: "logoutUser", sender: self)
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alert.addAction(defaultAction)
alert.addAction(cancelAction)
self.present(alert, animated: true, completion: nil)
}
else {
print("SMS FALSE successful logout")
PFUser.current()?["smsVerification"] = false
PFUser.current()?.saveInBackground()
self.performSegue(withIdentifier: "logoutUser", sender: self)
}
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
if (PFUser.current()?["saving"] == nil || PFUser.current()?["checking"] == nil) {
PFUser.logOut()
self.performSegue(withIdentifier: "logout", sender: self)
}
else {
switch2FA.addTarget(self, action: #selector(StatementViewController.switchMoved), for: UIControlEvents.valueChanged)
switchBoolValue = true
}
}

func switchMoved() { // stores value for the switch
if switch2FA.isOn {
switchBoolValue = true
print("switch on")
}
else {
switchBoolValue = false
print("switch off")
}
}

User Accounts Summary

Exécuter l'authentification 2FA pour un utilisateur vérifié lors d'une action spécifique

Verify Pin Screen

Transfer Funds

Pour les transactions plus sécurisées, telles qu'un transfert de fonds d'un compte à un autre, vous pouvez déclencher une demande de vérification pour confirmer l'action de la demande de l'utilisateur.

Ajoutez un nouveau contrôleur ("TransferPinViewController") avec un champ de texte ("pinCode" - IBOutlet) et un bouton ("verifyButton" - IBAction) dans le fichier storyboard. Créez une transition ("verifyTransfer") entre le "TransferViewController" et le contrôleur de vue nouvellement créé.

Les chèques, l'épargne, le montant du transfert, la source du transfert et le total après le transfert seront envoyés avec la séquence. Mettre à jour les fonctions de transfert ("checkingToSaving" et "savingToChecking") pour envoyer l'utilisateur au "TransferPinViewController" après avoir vérifié le solde disponible pour le transfert.

func checkingToSaving() {
print("checkingToSaving")
if checkingAmount - transferAmt > 0 {
print("NEWTOTAL: \(checkingAmount - transferAmt)")
transferSource = "checkingToSaving"
afterTransferTotal = checkingAmount - transferAmt
self.performSegue(withIdentifier: "verifyTransfer", sender: self)
}

else {
print("ERROR")
let alert = UIAlertController(title: "Transfer Error", message: "You do not have the requested transfer amount in your Checking Account. Please try again.", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "Back", style: .default, handler: nil)
alert.addAction(defaultAction)
self.present(alert, animated: true, completion: nil)

}
}
func savingToChecking() {
if savingAmount - transferAmt > 0 {
transferSource = "savingToChecking"
afterTransferTotal = savingAmount - transferAmt
self.performSegue(withIdentifier: "verifyTransfer", sender: self)
}
else {
print("ERROR")
let alert = UIAlertController(title: "Transfer Error", message: "You do not have the requested transfer amount in your Savings Account. Please try again.", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "Back", style: .default, handler: nil)
alert.addAction(defaultAction)
self.present(alert, animated: true, completion: nil)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any!) {
if (segue.identifier == "verifyTransfer") {
let verifyTransferVC = segue.destination as! TransferPinViewController;
verifyTransferVC.checkingAmount = checkingAmount
verifyTransferVC.savingAmount = savingAmount
verifyTransferVC.transferAmt = transferAmt
verifyTransferVC.transferSource = transferSource
verifyTransferVC.afterTransferTotal = afterTransferTotal
}
}

Créez une fonction qui appelle la méthode "getVerifiedUser" pour lancer la vérification de l'utilisateur. Cette fonction doit être appelée lors du chargement de la vue.

import NexmoVerify //Add to top of the file

override func viewDidLoad() {
super.viewDidLoad()
verify()
}
func verify() {
VerifyClient.getVerifiedUser(countryCode: "US", phoneNumber: PFUser.current()?["phoneNumber"] as! String,
onVerifyInProgress: {
},
onUserVerified: {
self.performTransfer()
},
onError: { verifyError in
switch (verifyError) {
case .invalidPinCode:
UIAlertView(title: "Wrong Pin Code", message: "The pin code you entered is invalid.", delegate: nil, cancelButtonTitle: "Try again!").show()
case .invalidCodeTooManyTimes:
let alert = UIAlertController(title: "Unsucessful Identification", message: "Logging out. Goodbye.", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "Goodbye", style: .default) {
UIAlertAction in
VerifyClient.cancelVerification() { error in
if let error = error {
// something wen't wrong whilst attempting to cancel the current verification request
return
}
}
self.performSegue(withIdentifier: "logout", sender: self)
}
alert.addAction(defaultAction)
self.present(alert, animated: true, completion: nil)
default:
print(verifyError.rawValue)
break
}
})
}

Comme indiqué ci-dessus, appelez la fonction "performTransfer" dans la méthode de rappel "onUserVerified". Comme nous l'avons fait dans le contrôleur de vue de vérification précédent, appelez la méthode "checkPinCode" dans votre bouton IBAction pour vérifier le code PIN fourni par l'utilisateur. Enfin, créez une transition ("sucessfulTransfer") entre le "VerifyPinViewController" et le "StatementViewController" pour renvoyer l'utilisateur à l'écran des relevés en cas de transfert réussi.

@IBOutlet weak var pincode: UITextField!
@IBAction func checkPin(sender: AnyObject) {
VerifyClient.checkPinCode(pincode.text!)
}
func performTransfer() {
if transferSource == "checkingToSaving" {
checkingAmount = checkingAmount - transferAmt
savingAmount = savingAmount + transferAmt
PFUser.current()?["checking"] = checkingAmount
PFUser.current()?["saving"] = savingAmount
PFUser.current()?.saveInBackground()
OperationQueue.main.addOperation {
self.performSegue(withIdentifier: "successfulTransfer", sender: self)
}
}
else if transferSource == "savingToChecking"{
savingAmount = savingAmount - transferAmt
checkingAmount = checkingAmount + transferAmt
PFUser.current()?["saving"] = savingAmount
PFUser.current()?.saveInBackground()
PFUser.current()?["checking"] = checkingAmount
PFUser.current()?.saveInBackground()
OperationQueue.main.addOperation {
self.performSegue(withIdentifier: "successfulTransfer", sender: self)
}
}
}

C'est tout ce que vous avez à faire pour activer l'authentification à deux facteurs dans votre app iOS à l'aide du SDK Verify de Nexmo.

De nos jours, l'activation de 2FA est indispensable pour gérer l'accès aux informations sensibles et garantir une identification correcte de l'utilisateur. Dans ce tutoriel, nous avons sécurisé l'application de démonstration avec les trois méthodes d'authentification. En utilisant la combinaison du nom d'utilisateur et du mot de passe d'un utilisateur, nous avons garanti quelque chose que l'utilisateur connaît (identifiants de connexion). En mettant en œuvre le SDK Verify iOS de Nexmo, nous nous sommes assurés de vérifier quelque chose que l'utilisateur a (accès à son téléphone en capturant l'ID de l'appareil et l'adresse IP de l'utilisateur). En ajoutant le Touch ID d'Apple, nous avons vérifié ce que l'utilisateur est (lui-même) en utilisant la vérification biométrique.

Le processus d'ajout de 2FA est simple grâce au SDK Verify et à l'API d'authentification locale d'Apple, et il ajoute une couche de sécurité supplémentaire qui protège les informations sensibles de vos utilisateurs.

N'hésitez pas à me faire part de vos réflexions ou de vos questions sur Twitter @sidsharma_27.

Partager:

https://a.storyblok.com/f/270183/150x150/a3d03a85fd/placeholder.svg
Sidharth Sharma