Ein System zur Zwei-Faktor-Authentifizierung ermöglicht es, eine zusätzliche Überprüfungsschicht bezüglich der Identität eines Benutzers hinzuzufügen, der sich bei einer Plattform oder Anwendung anmelden möchte. Es kann von Benutzern als Belastung angesehen werden, da es einen zusätzlichen Schritt erfordert, um auf den gewünschten Inhalt zuzugreifen, ist aber in bestimmten Fällen unerlässlich, um die Sicherheit der Benutzerdaten zu gewährleisten. Die Zwei-Faktor-Authentifizierung erschwert auch die automatisierte Anmeldung durch einen Bot, wodurch die Wahrscheinlichkeit von Spam und Betrug reduziert wird. Als starke Authentifizierungsmethode betrachtet, verpflichtet die Zwei-Faktor-Authentifizierung Ihre Benutzer, zwei verschiedene Identitätsnachweise zu erbringen. Man trifft diese Authentifizierungsmethode oft an, ohne es überhaupt zu merken, zum Beispiel bei der Zahlung mit Bankkarte. Tatsächlich ist das Bezahlen mit Ihrer Bankkarte durch Eingabe Ihres Geheimcodes eine Form der Zwei-Faktor-Authentifizierung, wobei der erste Nachweis der Besitz der Bankkarte und der zweite der Geheimcode ist.
Es gab eine Zeit, in der die Mehrheit der Zwei-Faktor-Authentifizierungen (A2F) per E-Mail erfolgte. Die Authentifizierung per E-Mail kann für den Benutzer mühsam sein: das eigene Postfach öffnen zu müssen, auf das E-Mail zu warten, es zu öffnen und dann den Code zu kopieren und einzufügen oder auf einen Link zu klicken, kann mehr als einen entmutigen. Zudem kann ein E-Mail-Postfach gleichzeitig auf einer Vielzahl verschiedener Geräte geöffnet sein, was die Anzahl möglicher Einbruchsvektoren erhöht.
Wie Sie sich dank des Titels dieses Artikels sicherlich schon gedacht haben, werden wir uns ansehen, wie man ein A2F-System mittels SMS implementiert. Das Prinzip ist, dass der Benutzer seine Authentifizierung durch Eingabe eines Codes bestätigt, den er per SMS erhält, genannt One Time Password (OTP). Dieses Mittel zur Zwei-Faktor-Authentifizierung ist user friendly, besonders mit der seit iOS Version 12 hinzugefügten Möglichkeit, ein Feld automatisch mit dem per SMS erhaltenen Code auszufüllen.
Im weiteren Verlauf dieses Artikels werden wir sehen, wie wir eine Zwei-Faktor-Authentifizierung per SMS auf einer Anwendung implementieren können, in
React Native.
Ablauf
Um dieses System zur Zwei-Faktor-Authentifizierung zu integrieren, betrachten wir zuerst die Abfolge der Ereignisse.
In unserer Anwendung, wenn ein Benutzer versucht, sich anzumelden, generieren wir ein OTP und speichern es in einer Datenbank unter Angabe eines Ablaufdatums. Mithilfe einer API senden wir diesen Code dann per SMS an den Benutzer, der ihn dann zur Beendigung der Authentifizierung eingeben kann.

Diagramm des Austauschs zwischen Frontend, Backend und der SMS-API
Voraussetzungen
Im weiteren Verlauf des Artikels gehen wir davon aus, dass ein Authentifizierungssystem mit Login und Passwort existiert, und wir erklären, wie man eine SMS-Verifizierung integriert. Wir gehen auch davon aus, dass die Telefonnummern der Benutzer in der Datenbank gespeichert sind.
Die folgenden Technologien werden verwendet:
SMS-Versanddienst
Um SMS mit den Verifizierungscodes zu senden, werden wir den Dienst
Twilio.
Twilio stellt auch zur Verfügung
Verify, eine All-in-One-API zur Verwaltung des Versands von Verifizierungscodes. In diesem Artikel werden wir, damit die vorgestellte Methode auf jeden SMS-Versanddienst anwendbar ist, die klassische SMS-Versand-API von Twilio verwenden.
Standardmässig wird dem Empfänger der SMS eine Absendernummer angezeigt. Wenn Sie möchten, dass der Absender im alphanumerischen Format angezeigt wird, können Sie dies unter
diesem Artikel.

Auf dem rechten Bildschirm ist der Absendername im alphanumerischen Format.
Erstellung und Versand des OTP
Sobald der Benutzer seine Anmeldedaten eingegeben hat und die Anwendung überprüft hat, dass diese korrekt sind, generieren wir ein OTP unter Verwendung der Bibliothek
generate-sms-verification-code :
import * as phoneToken from 'generate-sms-verification-code'
const generateUserVerificationCode = () => {
return phoneToken(4);
}
Hier wird ein 4-stelliger Code generiert.
Wir tragen den Code dann mit einem Ablaufdatum in die Datenbank ein:
await this.userRepository.update(user.userId, {
smsOTP: verificationCode,
otpExpirationDate: moment().add(5, 'm').toDate(),
});
Hier läuft der Code 5 Minuten nach seiner Generierung ab.
Wir müssen den Code nun per SMS über Twilio an den Benutzer senden. Dazu benötigen Sie Ihre Twilio Account SID und Ihr Twilio Auth Token, die beide über Ihre Twilio-Konsole zugänglich sind.
import * as twilio from 'twilio';
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = twilio(accountSid, authToken);
async sendSMSToUser(user: User, body: string) {
const smsSent = await client.messages.create({
body,
to: user.phoneNumber,
from: process.env.TWILIO_PHONE_NUMBER,
});
return !!smsSent.sid;
}
Der obige Code erstellt einen Twilio-Client, der verwendet wird, um die SMS-Versand-API mit der Methode aufzurufen
create des Objekts
messages. Sie finden den vollständigen Code für die Generierung und den Versand des in ein Authentifizierungssystem integrierten Codes
hier.
Eingabe des Verifizierungscodes
Da Ihre Benutzer nun einen Code erhalten, wenn sie versuchen, sich anzumelden, müssen sie diesen in Ihrer Anwendung eingeben können, um die Authentifizierung abzuschliessen. Dafür verwenden wir die Bibliothek
react-native-confirmation-code-field, die es ermöglicht, Textfelder speziell für Codes zu erstellen.

Beispiel eines in React Native programmierten Bildschirms zur Eingabe eines Codes
Diese Bibliothek gibt uns die Möglichkeit, automatisch eine Funktion aufzurufen, wenn der Verifizierungscode vollständig eingegeben wurde (dank der Eigenschaft onFulfill), sowie den per SMS gesendeten Code unter iOS automatisch auszufüllen.
In unserem Code haben wir diese Funktion benannt onCodeInputFulfilled : sie sendet den vom Benutzer eingegebenen Code an das Backend, welches dem Frontend eine Antwort zurücksendet, die angibt, ob der Code gültig ist oder nicht, gegebenenfalls mit einem Fehler. Je nach Ergebnis wird der Benutzer auf einen Erfolgsbildschirm weitergeleitet oder es wird ihm eine Fehlermeldung angezeigt.
const onCodeInputFulfilled = (value: string) => {
setIsProcessing(true);
submitVerificationCode(value, route.params.userId).then((res) => {
setIsProcessing(false);
if (res.success) {
navigation.navigate('SuccessScreen');
} else {
setErrorMessage(res.errorMessage);
}
});
};
Verifizierung des Codes
Hier ist der Backend-Code, um zu überprüfen, ob der per SMS gesendete Code gültig ist:
@Post('/verifyCode')
async verifyUserCode(@Body() data, @Res() res) {
const verificationResult = await this.userService.verifyUserCode(
data.userId,
data.verificationCode,
);
res.status(HttpStatus.OK).send({
success: verificationResult.success,
errorMessage: verificationResult.errorMessage,
});
}}
Hier wird die Funktion verifyUserCode nach einer Anfrage an die Route aufgerufen. /verifyCode. Sie ruft eine andere Funktion auf verifyUserCode die im NestJS-Dienst zur Verwaltung der Benutzer vorhanden ist, den wir hier genannt haben userService :
async verifyUserCode(userId: number, verificationCode: string) {
const retrievedUser = await this.userRepository.findOne({ userId });
if (verificationCode !== retrievedUser.smsOTP) {
return { success: false, errorMessage: 'Wrong verification code' };
} else if (moment().isAfter(retrievedUser.otpExpirationDate)) {
return { success: false, errorMessage: 'Verification code expired' };
} else {
return { success: true };
}
}
Diese Funktion überprüft, dass der vom Benutzer eingegebene Code und der generierte und in der Datenbank gespeicherte Code derselbe ist. Sie überprüft auch, dass der Code nicht abgelaufen ist.
Das Ergebnis wird anschliessend an das Frontend gesendet, gegebenenfalls mit einem Fehler.
Fazit
Bravo! Sie haben gerade gelernt, wie man ein Zwei-Faktor-Authentifizierungssystem mit einem per SMS gesendeten Verifizierungscode integriert, einschliesslich der automatischen Ausfüllung des unter iOS empfangenen Codes. Wir haben dies mit React Native und NestJS erreicht, aber die vorgestellte Logik kann auch auf andere Technologien angewendet werden.
Fassen wir zusammen, was wir in diesem Artikel gelernt haben. Um ein Zwei-Faktor-Authentifizierungssystem per SMS in eine einfache Authentifizierung zu integrieren, müssen Sie zunächst sicherstellen, dass Sie die Telefonnummern Ihrer Benutzer besitzen. Wenn der Benutzer in Ihrer Anwendung auf die Schaltfläche «Verbinden» klickt, muss auf Ihrem Backend eine Überprüfung der Anmeldedaten erfolgen. Sind diese korrekt, muss ein OTP generiert, in Ihrer Datenbank gespeichert und dem Benutzer zugeordnet und per SMS über eine SMS-Versand-API gesendet werden. Vom Backend aus, wenn Sie die Bestätigung des SMS-Versands erhalten, können Sie dann eine Antwort an das Frontend zurücksenden, um den SMS-Versand zu bestätigen. Sobald die Anwendung diese Bestätigung erhält, muss der angezeigte Bildschirm für den Benutzer geändert und ihm die Möglichkeit gegeben werden, das soeben erhaltene OTP einzugeben. Wenn der Benutzer den erhaltenen Code eingegeben hat, muss dieser dann mittels einer Anfrage an das Backend zur Validierung gesendet werden. Die Validierung des OTP erfolgt durch den Vergleich des vor dem SMS-Versand in der Datenbank gespeicherten Codes mit dem in der Anwendung eingegebenen Code (unter Überprüfung des Ablaufdatums). Wenn der eingegebene Code korrekt ist, wird der Benutzer authentifiziert und kann auf den entsprechenden Bildschirm weitergeleitet werden.
Um die Benutzererfahrung zu verbessern, wird empfohlen, eine Schaltfläche anzuzeigen, die das erneute Senden des Codes ermöglicht, falls dieser nicht empfangen wurde. Es ist ratsam, diese nach dem Drücken für 15 bis 30 Sekunden zu deaktivieren, um eine sehr grosse Anzahl von Sendungen zu vermeiden, die kostspielig sein und das Backend der Anwendung überlasten könnten.
Hier ist der Quellcode des implementierten Systems:
Abschliessend sehen Sie hier ein GIF, das den vollständigen Ablauf des frisch implementierten Authentifizierungssystems zeigt:
Referenzen