
Hinzufügen von Telefon- und biometrischer Verifizierung zu Ihrer iOS-Anwendung
Lesedauer: 10 Minuten
Zwei-Faktor-Authentifizierung (2FA) bietet eine zusätzliche Sicherheitsebene für Benutzer, die auf sensible Informationen zugreifen. Es gibt mehrere Arten von 2FA, wie z. B.:
Etwas, das Sie wissen (Benutzername, Passwort)
Etwas, das Sie haben (Ihr Telefon/SIM)
Etwas, das Sie sind (Biometrischer Fingerabdruck oder Retina-Scan)
In diesem Tutorial zeigen wir Ihnen, wie Sie alle drei Funktionen zu einer iOS-Applikation hinzufügen können, indem Sie das Nexmo Verify SDK.
Vonage API-Konto
Um dieses Tutorial durchzuführen, benötigen Sie ein Vonage API-Konto. Wenn Sie noch keines haben, können Sie sich noch heute anmelden und mit einem kostenlosen Guthaben beginnen. Sobald Sie ein Konto haben, finden Sie Ihren API-Schlüssel und Ihr API-Geheimnis oben auf dem Vonage-API-Dashboard.
In diesem Lernprogramm wird auch eine virtuelle Telefonnummer verwendet. Um eine zu erwerben, gehen Sie zu Rufnummern > Rufnummern kaufen und suchen Sie nach einer Nummer, die Ihren Anforderungen entspricht.
Erste Schritte
Durch die Verwendung des SDK können Sie eine zusätzliche Sicherheitsebene hinzufügen. Sie können sicherstellen, dass der Benutzer an ein bestimmtes physisches Gerät gebunden ist, indem Sie die Geräte-ID und einen SMS/TTS-PIN-Code erfassen. Durch die Bestätigung, dass sich der Benutzer von demselben Gerät aus anmeldet wie beim letzten Anmeldeversuch, wird Spam/Betrug verhindert.
Wir werden eine Startanwendung (Swift 3) verwenden, die eine Back4App Backend für die Benutzeranmeldung verwendet (etwas, das Sie kennen). Wir werden das Verify SDK für unsere 2FA-Lösung über SMS und TTS und Apples Touch ID für die biometrische Verifizierung verwenden (etwas, das Sie kennen).
Richten Sie Ihre Back{4}App-Datenbank ein
Back{4}App ist ein Backend, mit dem Sie Parse-Anwendungen erstellen und hosten können (was praktisch ist, da Parse geschlossen wurde). Wenn Sie noch keinen Back{4}App Account haben, melden Sie sich an und erstellen Sie eine Anwendung.

Sobald Ihre Anwendung erstellt ist, klicken Sie im Abschnitt "Grundeinstellungen" auf die Schaltfläche "Server". Sie werden dann zu einer Seite mit Ihren neuen Anmeldedaten für die Anwendung weitergeleitet. Sobald Sie Ihre Anwendungs-ID und Ihren Client-Schlüssel notiert haben, klicken Sie auf die Schaltfläche "Zurück" und gehen Sie zum "Dashboard" im Abschnitt "Grundeinstellungen". Sobald Sie zum Dashboard weitergeleitet werden, gehen Sie zum Abschnitt "Core", klicken Sie auf "Edit" (oben rechts) und fügen Sie die folgenden Spalten zur Klasse "User" hinzu:
Überprüfung" (Nummer)
Speichern (Nummer)
sitekey" (Datei - Bild für Benutzer)
phoneNumber (Zeichenfolge)
smsVerification" (boolescher Wert - Benutzer können die SMS-Überprüfung bei der Anmeldung aktivieren)

Jetzt, wo Back{4} apps eingerichtet ist, können wir uns an die Einrichtung unserer Startanwendung machen.
Holen Sie sich die Starter App
Beginnen wir damit, die Starter-App von GitHub zu holen. Führen Sie in Ihrem Terminal den folgenden Befehl aus:
Das Repo hat einen Getting-Started-Zweig (vor 2FA), der es Ihnen ermöglicht, dem untenstehenden Tutorial zu folgen, und einen Master-Zweig, der die endgültige Version dieses Tutorials enthält.
Öffnen Sie die NexmoBankingApp.xcproj in XCode. Wählen Sie "NexmoBankingApp", um Ihre App-Einstellungen zu öffnen, und aktualisieren Sie den "Bundle Identifier" des Projekts auf einen gültigen Bezeichner und App-Namen, der im Developer Portal von Apple registriert ist. Fügen Sie Ihre Back4App Anwendungs-ID und Ihren Client Key in AppDelegate.swift.
let configuration = ParseClientConfiguration {
$0.applicationId = "BACK4APP_APP_ID"
$0.clientKey = "BACK4APP_CLIENT_KEY"
$0.server = "https://parseapi.back4app.com"
}
Parse.initializeWithConfiguration(configuration)Nach der Eingabe gehen Sie zu "ViewController.swift" und fügen der Datenbank einen Dummy-Benutzer hinzu, indem Sie den Aufruf der Funktion "signUpDemoAccount()" in der Methode "viewDidLoad()" in "ViewController.swift" auskommentieren:
override func viewDidLoad() {
super.viewDidLoad()
self.onlineID.delegate = self
signUpDemoAccount() //Uncomment to create dummy user
}Aktualisieren Sie die Felder Benutzername, Passwort, E-Mail und Telefonnummer des PFUser in der Funktion '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.")
}
}
}
Starten Sie die Anwendung. Der PFUser wird erstellt und füllt das Back4App-Dashboard auf. Um zu vermeiden, dass ein weiterer Benutzer erstellt wird, wenn Sie die App erneut starten, sollten Sie den Aufruf der Funktion "signUpDemoAccount()" in der Methode "viewDidLoad()" auskommentieren, nachdem Sie die App das erste Mal ausgeführt haben.

Starten Sie die Anwendung erneut. Sie können auf die Account-Informationen des Benutzers zugreifen, indem Sie die Anmeldedaten des neu erstellten Benutzers eingeben.
Okay, jetzt wollen wir die Sicherheit in der App durch Hinzufügen von 2FA erhöhen.
Einrichten Ihrer Nexmo-App
Melden Sie sich für einen Nexmo Account an und gehen Sie zu Ihrem Kunden-Dashboard. Klicken Sie auf die Registerkarte Verify und fügen Sie eine neue Anwendung unter "Ihre Applications" hinzu. Legen Sie einen Namen für Ihre Anwendung fest, sowie die Leerlaufzeit von Instant (maximale Zeitspanne, in der der Nutzer verifiziert bleibt; in diesem Fall laufen die Nutzer sofort ab) und die Länge des PIN-Codes.

Als nächstes fügen wir das Nexmo Verify SDK hinzu. Das Verify SDK kann mit Hilfe von Cocoapods einfach zu Ihrem Projekt hinzugefügt werden. Erstellen Sie eine Poddatei in Ihrem Projektverzeichnis, fügen Sie den 'NexmoVerify'-Pod in die Datei ein und installieren Sie den Pod über Terminal. (Wenn der Pod nicht gefunden wird, führen Sie pod update aus, um Cocoapods zu aktualisieren).
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’
endSobald die Pod-Installation abgeschlossen ist, schließen Sie Xcode und öffnen Sie die neue Projektdatei "xcworkspace". Jetzt können Sie in den Code eintauchen!
Wenn Sie mehr über den NexmoVerify Pod erfahren möchten, können Sie den Quellcode auf Github.
Eintauchen in den Code
Nun, da Sie Ihre Abhängigkeiten eingerichtet und die Nexmo-Anmeldedaten erhalten haben, ist es an der Zeit, diese zu Ihrer "AppDelegate"-Datei hinzuzufügen.
In AppDelegate.swift:
import NexmoVerify //Add to top of the file
fileprivate var appID = "YOUR_NEXMO_APP_ID"
fileprivate var sharedSecret = "YOUR_NEXMO_SHARED_SECRET" Nexmo-Client initialisieren
Initialisieren Sie den Nexmo-Client in der Funktion "didFinishLaunchingWithOptions" der Datei "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
}
Hinzufügen der biometrischen Verifizierung zum SitekeyViewController
Nach erfolgreicher Anmeldung, da wir Back4Apps die Kombination aus Benutzername und Passwort mitgeteilt haben, führt der zweite Bildschirm den Benutzer zur Verifizierung seines Sitekeys, wo wir die biometrische Touch-ID-Verifizierung hinzufügen werden.
Wenn der Benutzer die Anmeldeschaltfläche drückt, verwenden wir die LocalAuthentication-API von Apple, um eine Touch-ID-Verifizierung durchzuführen. Wenn das Gerät nicht mit Touch ID kompatibel ist (kein Fingerabdruckleser), überspringt der Benutzer die biometrische Verifizierung. Fügen Sie einen Übergang ('signInStopped') hinzu, so dass der Benutzer, wenn er die Touch-ID-Verifizierung nicht erfolgreich bestehen kann, abgemeldet wird und zur Anmeldeseite zurückkehrt. Je nach Einstellung des Benutzers für die SMS-Verifizierung löst die Funktion "Workflow fortsetzen" eine Verifizierungsanforderung aus, nachdem sie zum Bildschirm für die PIN-Verifizierung übergegangen ist (den wir als Nächstes erstellen) oder die Seite des Benutzerkontos anzeigt.
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)
}
}

View Controller für die Verifizierung hinzufügen und 2FA-Logik zum VC hinzufügen
Fügen Sie eine neue Datei zu Ihrem Projekt hinzu ('VerifyPinViewController') und erstellen Sie im Storyboard mit dem Interface Builder einen View Controller. Öffnen Sie das Menü 'Utilities', indem Sie auf die Schaltfläche oben rechts im Interface Builder klicken. Klicken Sie auf die Schaltfläche 'Identity Inspector' und geben Sie den Namen der neuen Klasse ein, nachdem Sie auf die Verknüpfung des View Controllers im IB mit der Datei geklickt haben. Als nächstes fügen Sie ein Textfeld ('pinCode' - IBOutlet) zusammen mit einer Schaltfläche ('verifyPin' - IBAction) hinzu, um den Pin-Code zu übermitteln. Erstellen Sie eine Segue ('verifyPin'), die mit dem 'SitekeyViewController' und dem neu erstellten View Controller verbunden ist.
Rufen Sie in der Methode "viewDidAppear" des neu hinzugefügten View-Controllers die folgende Funktion auf.
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)
}
Holen Sie die Telefonnummer des Benutzers aus der Back4Apps-Datenbank und lösen Sie eine Verifizierungsanfrage mit der Methode getVerifiedUser() aus. Erstellen Sie eine Segue ('pinVerified'), die von 'VerifyPinController' mit 'StatementViewController' verbunden ist.
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
}
})
}Rufen Sie außerdem die checkPinCode Methode auf, die vom Nexmo-Client bereitgestellt wird, wenn die Taste gedrückt wird, um die vom Benutzer angegebene PIN zu verifizieren.
@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!)
}
} Option für SMS-Bestätigung bei der Anmeldung hinzufügen
Als Nächstes fügen Sie die Logik hinzu, die es dem Benutzer ermöglicht, die SMS-Überprüfung zu aktivieren. Fügen Sie Ihrem "StatementViewController" ein Schalter-Benutzeroberflächenelement als IBOutlet hinzu. Fügen Sie außerdem eine boolesche Variable hinzu, die den Wert des Schalters enthält. Der Wert des Schalters wird beim Abmelden des Benutzers in der Datenbank gespeichert. Wenn der Schalter aktiviert wurde, wird bei der nächsten Anmeldung eine SMS-Überprüfung ausgelöst. Überprüfen Sie nach dem Erscheinen der Ansicht die Werte für das Giro- und das Sparkonto, um sicherzustellen, dass sie nicht gleich Null sind.
@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")
}
}
2FA für verifizierte Benutzer bei bestimmten Aktionen durchführen


Für sicherere Transaktionen, z. B. wenn ein Benutzer Geld von einem Konto auf ein anderes überweist, können Sie eine Verifizierungsanfrage auslösen, um die Benutzeranforderung zu bestätigen.
Fügen Sie einen neuen Controller ('TransferPinViewController') mit einem Textfeld ('pinCode' - IBOutlet) und einer Schaltfläche ('verifyButton' - IBAction) in der Storyboard-Datei hinzu. Erstellen Sie eine Segue ('verifyTransfer') vom 'TransferViewController' zum neu erstellten View-Controller.
Die Girokonten, die Ersparnisse, der Überweisungsbetrag, die Überweisungsquelle und die Gesamtsumme nach der Überweisung werden mit dem Segue gesendet. Aktualisieren Sie die Überweisungsfunktionen ("checkingToSaving" und "savingToChecking"), um den Benutzer zum "TransferPinViewController" zu schicken, nachdem der verfügbare Saldo für die Überweisung überprüft wurde.
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
}
}
Erstellen Sie eine Funktion, die die Methode "getVerifiedUser" aufruft, um die Benutzerüberprüfung einzuleiten. Diese Funktion sollte aufgerufen werden, wenn die Ansicht geladen wird.
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
}
})
}Wie oben gezeigt, rufen Sie die Funktion "performTransfer" innerhalb der Callback-Methode "onUserVerified" auf. Rufen Sie, wie im vorherigen Verifizierungs-View-Controller, die Methode "checkPinCode" innerhalb Ihrer IBAction-Schaltfläche auf, um die vom Benutzer angegebene PIN zu überprüfen. Schließlich erstellen Sie eine Überleitung ('sucessfulTransfer') vom 'VerifyPinViewController' zum 'StatementViewController', um den Benutzer bei erfolgreicher Übertragung zum Bildschirm 'Statements' zurückzubringen.
@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)
}
}
}Das ist alles, was Sie tun müssen, um die Zwei-Faktor-Authentifizierung in Ihrer iOS-App mit dem Verify SDK von Nexmo zu aktivieren.
Heutzutage ist die Aktivierung von 2FA ein Muss, um den Zugang zu sensiblen Informationen zu verwalten und eine ordnungsgemäße Benutzeridentifizierung sicherzustellen. In diesem Lernprogramm haben wir die Demo-Anwendung mit allen drei Authentifizierungsmethoden gesichert. Mit der Kombination aus Benutzernamen und Passwort haben wir sichergestellt, dass der Benutzer etwas weiß (Anmeldedaten). Durch die Implementierung von Nexmos Verify iOS SDK haben wir sichergestellt, dass wir etwas verifiziert haben, das der Benutzer hat (Zugriff auf sein Telefon durch Erfassung der Geräte-ID und IP-Adresse des Benutzers). Durch die Hinzufügung von Apples Touch ID wurde etwas sichergestellt, das der Benutzer ist (er selbst), indem eine biometrische Verifizierung verwendet wurde.
Das Hinzufügen von 2FA ist mit dem Verify SDK und der lokalen Authentifizierungs-API von Apple ganz einfach und fügt eine zusätzliche Sicherheitsebene hinzu, die die sensiblen Daten Ihrer Benutzer schützt.
Sie können mir gerne Ihre Gedanken oder Fragen auf Twitter schicken @sidsharma_27.
