So verifizieren Sie einen Nutzer per SMS mit JavaScript und Twilio Verify

August 27, 2021
Autor:in:
Prüfer:in:

So verifizieren Sie einen Nutzer per SMS mit JavaScript und Twilio Verify

Viele Anwendungen überprüfen und autorisieren ihre Benutzer, indem sie einen numerischen Code, das sogenannten Einmalkennwort, entweder per Sprachanruf oder per SMS, an die Telefonnummer des Benutzers senden.

In diesem Artikel erfahren Sie, wie Sie die SMS-Benutzer-Verifizierung mit Twilio Verify durchführen. Sie werden ein abgespecktes Frontend mit JavaScript und HTML sowie ein Node.js-Backend erstellen, alles gehostet mit Twilio Functions und gebaut mit dem Twilio Serverless Toolkit, einem Plugin für die Twilio-CLI.

Voraussetzungen

Um mit diesem Tutorial zu beginnen, benötigen Sie Folgendes:

Einrichtung von Twilio Functions

Führen Sie in Ihrem Terminal oder der Kommandozeile aus Ihrem Hauptprojekt- oder Entwicklungsordner den folgenden Befehl aus, um einen neuen Functions-Dienst zu erstellen.

twilio serverless:init --empty verify-demo

Dadurch wird ein neues Verzeichnis mit dem Namen verify-demo auf Ihrem Computer erstellt, das einige Boilerplate-Ordner und Dateien für einen Twilio Functions-Dienst enthält.

Ihre Frontend-Codedateien werden im Ordner verify-demo/assets und die Backend-Codedateien in den Ordner verify-demo/functions gelegt.

Sie sehen auch eine .env-Datei im Ordner verify-demo. Diese Datei wird automatisch mit Ihrer Twilio-Konto-SID und Ihrem Auth-Token vorausgefüllt. Überprüfen Sie, ob diese Werte korrekt sind (Sie finden sie in Ihrem Haupt-Dashboard in der Twilio-Konsole) und vervollständigen sie falls nötig. Fügen Sie dann in einer neuen Zeile darunter folgenden Text hinzu:

VERIFY_SERVICE_SID=XXXX

Das XXXX ist ein Platzhalter, den Sie nachher ersetzen werden. Lassen Sie diese Datei also erst einmal offen.

Twilio-Konfiguration

Für die Verwendung von Twilio Verify richten Sie zunächst einen neuen Twilio Verify-Dienst ein. Ein Dienst besteht aus einem Satz von Konfigurationen, mit denen Sie Verifizierungen auf Ihrer App oder Website verwalten können.

Einen neuen Verify-Dienst erstellen

Navigieren Sie zum Abschnitt Verify der Twilio-Konsole und wählen Sie auf der linken Seite die Option Services aus. Klicken Sie auf das blaue Pluszeichen (+), um einen neuen Dienst zu erstellen. Ein modales Dialogfeld wird angezeigt, in dem Sie einen Namen für Ihren Dienst eingeben können. Nennen Sie es node-demo oder geben Sie ihm einen beliebigen anderen kurzen, beschreibenden Namen.

Nachdem Sie Ihren Dienst erstellt haben, werden Sie zu einer Seite für allgemeine Einstellungen für Ihren neuen Dienst weitergeleitet.

Twilio Service Einstellungen

Unter dem Namen Ihres Dienstes sehen Sie Ihre SERVICE-SID. Kopieren Sie diesen Wert und fügen Sie ihn in Ihre .env-Datei ein, indem Sie den Platzhalter XXXX durch die Variable VERIFY_SERVICE_SID ersetzen.

Speichern sie die .env-Datei und schließen sie.

Scrollen Sie in weiter unten auf der Seite „Service Settings“ (Einstellungen für Verify-Dienst) zum Abschnitt Delivery Channels (Kommunikationskanäle). Da Sie in diesem Beispiel nur SMS verwenden werden, sollten Sie die Kanäle „CALL“, „EMAIL“ und „WHATSAPP“ (Anrufe, E-Mails und WhatsApp Nachrichten) deaktivieren.

Klicken Sie auf Save (Speichern), um Ihre Änderungen zu speichern. Gratuliere, Ihr SMS-Verifizierungsdienst ist jetzt vollständig konfiguriert und Sie können mit dem Programmieren der Anwendung beginnen!

Frontend einrichten

In diesem Abschnitt richten Sie das Frontend Ihrer App ein.

Erstellen Sie dazu eine neue Datei mit dem Namen index.html im Ordner verify-demo/assets. Öffnen Sie diese Datei in Ihrem bevorzugten Texteditor und fügen Sie die folgende HTML hinzu:

<!DOCTYPE html>
<html>
  <head>
    <title>Verify SMS Demo</title>
  </head>

  <body>
    <form id="phone-form">
      <h2>Enter your phone number with country code:</h2>
      <input type="tel" id = "phone-number-input" placeholder="e.g. 15551235555"/>
      <input id="phone-submit" type="submit"/>
    </form>

    <form id="verify-form">
      <h2>Enter your verification code:</h2>
      <input type="number" id="otp-input" placeholder="e.g. 123456"/>
      <input id="verify-submit" type="submit"/>
    </form>

    <div id="response-text"></div>
  </body>

  <script type="text/javascript" src = "script.js"></script>
</html>

Diese HTML-Seite beinhaltet zwei Formulare: In dem einen gibt der Benutzer seine Telefonnummer ein, in dem anderen den Verifizierungscode, den er auf das Senden seiner Telefonnummer per SMS erhält. Außerdem wird ein leeres Element <div></div> erstellt, das dem Benutzer schließlich eine Erfolgs- oder Fehlermeldung anzeigt.

Diese beide Formulare sollen nicht gleichzeitig sichtbar sein. Also fügen Sie das folgende CSS zwischen den <head></head> Tags, unter dem Element <title>, ein, um das Formular #verify-form (und das leere <div></div>) beim Laden der Seite zu verbergen:

<style>
  #verify-form,
  #response-text {
    display: none;
  }
</style>

Programmcode für die Bearbeitung der Formulare

Erstellen Sie eine weitere Datei im Ordner verify-demo/assets mit dem Namen script.js. Hier schreiben Sie den Code zur Verarbeitung der Formulare und verbinden ihn mit der Twilio-API.

Fügen Sie oben in script.js den folgenden Code ein:

const phoneForm = document.getElementById('phone-form');
const verifyForm = document.getElementById('verify-form');
const responseText = document.getElementById('response-text');

let phoneNumber;

Dieser Code deklariert einige Variablen, die Sie im Skript verwenden werden.

Fügen Sie unter den Variablen-Deklarationen folgenden Code ein, um alle Einreichungen des #phone-form zu verarbeiten:

phoneForm.addEventListener('submit', async e => {
  e.preventDefault();

  phoneNumber = document.getElementById('phone-number-input').value;

  const response = await fetch('/send-notification', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({phoneNumber : phoneNumber })
  }).catch(e => console.log(e));

  if (response.ok) {
    phoneForm.style.display = 'none';
    verifyForm.style.display = 'block';
  }
});

Dieser Code wartet auf ein submit-Ereignis im #phone-form. Immer wenn dieses submit-Ereignis eintritt, wird eine asynchrone Funktion ausgeführt, die die folgenden Aufgaben erfüllt:

  • Verhindern, dass das Formular mehrmals gesendet wird
  • Erfassen des Werts für die Telefonnummer, die der Benutzer im Feld #phone-number-input eingegeben hat
  • Stellen einer POST-Anfrage mit der Telefonnummer an den Backend-Endpunkt /send-notification,
  • Umschalten des sichtbaren Formulars nach erfolgreicher Antwort von der Anfrage

Fügen Sie unter dem gesamten vorhandenen Code den folgenden Code hinzu, um die #verify-form-Einreichungen zu verarbeiten:

verifyForm.addEventListener('submit', async e => {
  e.preventDefault();

  const otp = document.getElementById('otp-input').value;

  const data = {
    phoneNumber: phoneNumber, 
    otp: otp
  };

  const response = await fetch('/verify-otp', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
    body: JSON.stringify(data)
  }).catch(e => console.log(e));

  const check = await response.json();

  const text = response.ok ? check.status : response.statusText;
  responseText.innerHTML = text;

  verifyForm.style.display = 'none';
  responseText.style.display = 'block';  
});

Dieser Code funktioniert ähnlich wie der, den Sie im vorherigen Schritt eingefügt haben, nur dass er während der Verifizierungsphase verwendet wird. Der Hauptunterschied besteht darin, dass dieser Code den Wert sowohl der Telefonnummer als auch des vom Benutzer übermittelten OTP an den Endpunkt /verify-otp sendet.

Wenn er eine Antwort von der POST-Anfrage erhält, zeigt er dem Benutzer den Verifizierungsstatus über das Element #response-text an.

Speichern und schließen Sie Ihre script.js-Datei. Jetzt ist das Backend dran.

Einrichten des Backends

Im obigen Code haben Sie POST-Anfragen an zwei Backend-Endpunkte gerichtet: /send-notification und /verify-otp. Diese Endpunkte werden Sie jetzt erstellen.

Verifizierungscode an den Benutzer senden

Der Endpunkt /send-notification empfängt die Telefonnummer des Benutzers und sendet über die Twilio Verify-API ein OTP per SMS an die Telefonnummer. Dadurch wird der Verifizierungsprozess eingeleitet.

Erstellen Sie im Ordner verify-demo/functions eine Datei mit dem Namen send-notification.js. Kopieren Sie folgenden Code und fügen Sie ihn in Ihre neue Datei send-notification.js ein:

exports.handler = function (context, event, callback) {
    const client = context.getTwilioClient();
   
    client.verify
      .services(context.VERIFY_SERVICE_SID)
      .verifications.create({ to: `+${event.phoneNumber}`, channel: "sms" })
      .then((verification) => {
        console.log(verification.status);
        return callback(null);
      })
      .catch((e) => {
        console.log(e);
        return callback(e);
      });
  };

Bei der Verwendung von Twilio Functions können Sie auf POST-Anfragedaten des event-Objekts zugreifen (dieses Objekt steht der Funktion immer zur Verfügung).

Überprüfen Sie das vom Benutzer eingereichte OTP

Der Endpunkt /verify-otp empfängt sowohl die Telefonnummer des Benutzers als auch das vom Benutzer eingereichte OTP. Mit der Twilio Verify-API überprüft dieser Endpunkt, ob das übermittelte OTP korrekt ist, und gibt eine Antwort mit Daten zu dieser Verifikationsprüfung, einschließlich Status, zurück.

Eine Verifizierungsprüfung kann drei Status haben: pending, approved oder canceled (aussstehend, genehmigt oder storniert).

  • Verifizierungsprüfungen mit Status pending wurden initiiert, aber nicht genehmigt oder storniert und sind nicht abgelaufen.
  • Verifizierungsprüfungen mit Status approved sind Verifizierungen, bei denen das OTP als übereinstimmend bestätigt wurde.
  • Verifizierungsprüfungen mit Status canceled wurden entweder storniert oder sind abgelaufen, da der Verifizierungscode vor mehr als 10 Minuten an den Benutzer gesendet wurde.

Erstellen Sie eine neue Datei im Ordner verify-demo/functions mit dem Namen verify-otp.js. Fügen Sie dieser Datei folgenden Code hinzu:

exports.handler = async function(context, event, callback) {
  const client = context.getTwilioClient();

  const check = await client.verify.services(context.VERIFY_SERVICE_SID)
    .verificationChecks
    .create({to: `+${event.phoneNumber}`, code: event.otp})
    .catch(e => {
      console.log(e)
      return callback(e)
    });
  
  const response = new Twilio.Response();
  response.setStatusCode(200);
  response.appendHeader('Content-Type', 'application/json');
  response.setBody(check);

  return callback(null, response);
}

Dieser Code führt die Verifizierungsprüfung mit der Telefonnummer und dem vom Benutzer eingereichten OTP durch. Anschließend erstellt er ein neues Response-Objekt und gibt die Verifizierungsdaten in der Antwort zurück.

Testen Sie Ihre App

Zeit, die App zu testen! Navigieren Sie in der Kommandozeile zum Verzeichnis verify-demo, falls Sie noch nicht dort sind. Führen Sie folgenden Befehl aus, um den lokalen Entwicklungsserver zu starten:

twilio serverless:start

Dadurch wird ein lokaler Server auf Port 3000 gestartet.

Navigieren Sie in Ihrem Browser zu http://localhost:3000/index.html, um Ihre App anzuzeigen.

Screenshot showing form to enter user phone number

Geben Sie Ihre Telefonnummer in das Feld ein, beginnend mit der Ländervorwahl, und klicken Sie dann auf die Schaltfläche Submit (Senden).

Sobald Sie auf die Schaltfläche Submit (Senden) klicken, wird das Formular für die Telefonnummer durch das Formular für den Verifizierungscode ersetzt. Außerdem erhalten Sie nach wenigen Augenblicken per SMS das OTP.

Das OTP ist als SMS angekommen

Kehren Sie zurück zu Ihrem Browser und senden Sie dieses OTP im Verifizierungsformular:

Screenshot of app showing OTP in input field

Wenn Sie auf Submit (Senden) klicken, wird der von Ihnen erstellte Endpunkt /verify-otp aufgerufen. Wenn Sie den richtigen Code in das Formular eingegeben haben, wird, sobald das Frontend Ihrer App eine Antwort vom Backend erhält, die Statusmeldung „approved“ angezeigt:

screenshot showing approved verification check status

Wenn Sie den falschen Code eingegeben haben, würde die Meldung stattdessen „pending“ lauten. In einer Produktionsapp würden Sie dem Benutzer wahrscheinlich die Möglichkeit geben, den Code erneut einzugeben, indem anstelle der Meldung „pending“ das Verifizierungsformular ein zweites Mal angezeigt wird.

Bereitstellen Ihrer Twilio-Funktionen

Bisher wurde Ihre App nur lokal auf Ihrem Computer ausgeführt. Wenn Sie eine lokal betriebene App bereitstellen möchten, die mit Twilio Functions erstellt wurde, können Sie aus dem Stammverzeichnis Ihres Projektordners (in diesem Fall node-demo) den folgenden Befehl ausführen:

twilio serverless:deploy

Dadurch wird jede Funktion Ihrer App über eine öffentlich zugängliche URL bereitgestellt.

Wie geht es weiter mit der Authentifizierung von Benutzern mit Twilio Verify?

Ich gratuliere zu Ihrer Umsetzung sicherer Praktiken und zur Einbindung von Sicherheitsmaßnahmen in Ihr Projekt!

Twilio Verify unterstützt neben SMS noch andere Kanäle, über die der Benutzer sich verifizieren kann, darunter Sprache, WhatsApp und E-Mail. Weitere Informationen zu diesen und anderen Verifizierungsmethoden finden Sie in der Dokumentation.

Erzählen Sie mit über Twitter, ob Sie die Twilio Verify-API dazu verwenden konnten, Benutzer in Ihrem Projekt zu schützen!

Ashley ist JavaScript-Redakteurin für den Twilio-Blog. Wenn du ihr technische Artikel über Twilio zukommen lassen möchtest, dann findest du sie unter @ahl389 auf Twitter. Wenn du sie dort nicht findest, dann sitzt sie vermutlich irgendwo auf einer Terrasse und trinkt Kaffee (oder ein Glas Wein, je nach Tageszeit).