Überprüfen von Telefonnummern in einer Spring Boot-App mit der Twilio Lookup-API

April 06, 2020
Autor:in:

Überprüfen von Telefonnummern in einer Spring Boot-App mit der Twilio Lookup-API


Hallo und Danke fürs Lesen! Dieser Blogpost ist eine Übersetzung von Validating phone numbers in a Spring Boot app using the Twilio Lookup API. Während wir unsere Übersetzungsprozesse verbessern, würden wir uns über Dein Feedback an help@twilio.com freuen, solltest Du etwas bemerken, was falsch übersetzt wurde. Wir bedanken uns für hilfreiche Beiträge mit Twilio Swag :)

Viele Benutzerregistrierungsabläufe fordern heutzutage Benutzer auf, ihre Telefonnummer einzugeben. Diese wird entweder für die Zwei-Faktor-Authentisierung oder zum Bereitstellen von Benachrichtigungen und Updates verwendet.

Um zu überprüfen, ob die vom Benutzer bereitgestellte Nummer auch gültig ist, sind wir vielleicht versucht, auf einen regulären Ausdruck zurückzugreifen. Das ist allerdings nicht zuverlässig. Telefonnummern sind eine komplizierte Angelegenheit, und ein regulärer Ausdruck gibt uns keine Auskunft darüber, ob die angegebene Nummer auch tatsächlich erreichbar ist. Es gibt mehrere Ebenen der Überprüfung. In diesem Blog zeige ich, wie wir mit  Twilio Lookup-API die Gültigkeit einer Telefonnummer überprüfen können.

Für die Demo-Anwendung verwenden wir Spring Boot. Anhand des Bean Validation-Frameworks zeige ich, wie wir eine @ValidPhoneNumber-Annotation erstellen. Diese kann ähnlich wie @NotNull verwendet werden.

Voraussetzungen

Bevor wir beginnen, benötigen wir Folgendes:

  • Ein Twilio-Konto. Wenn du dich über diesen Link registrierst, erhältst du ein Guthaben von 10 $ bei einem Upgrade des Kontos.
  • Installiertes Java (Java 8 oder höher). Meine bevorzugte Methode zur Installation von Java ist mit SDKMAN!
  • git

Wir beginnen mit dem Klonen des Demo-Repositorys aus GitHub am no-validation-Tag:

git clone git@github.com:mjg123/twilio-lookup-api-spring-boot-demo.git -b no-validation
cd twilio-lookup-api-spring-boot-demo

Mit dem Befehl ./mvnw spring-boot:run starten wir die Anwendung. Wir wissen, dass die Anwendung ausgeführt wird, wenn die Protokollmeldungen in der Zeile, die Started PhoneNumberLookupDemoApplication enthält, enden.

Jetzt können wir http://localhost:8080 aufrufen. Wir sollten Folgendes sehen:

UI für diesen Telefonnummern-Überprüfer – eine Webseite mit Feldern für „Name“ und „Telefonnummer“

Wenn wir versuchen, auf die Schaltfläche „Submit“ (Senden) zu klicken, ohne einen Namen oder eine Telefonnummer einzugeben, erhalten wir Fehlermeldungen. Wenn wir in beide Felder entsprechende Werte eingeben, wird uns die andere Seite in dieser App angezeigt:

Die App-UI, in der jemand erfolgreich „Haha - this isn't my phone number“ (Haha - das ist nicht meine Telefonnummer) als Telefonnummer verwendet hat. Das müssen wir ändern.

Sehen wir uns an, wie diese Überprüfung im Servercode konfiguriert wurde. Wir öffnen über unsere IDE die Person-Klasse im lol.gilliard.twiliolookupdemo-Paket. Uns wird der folgende Codeabschnitt angezeigt:

@NotNull
@NotBlank(message="Please enter your name")
private String name;

@NotNull
@NotBlank(message="Please enter your phone number")
private String phoneNumber;

Diese Annotationen sind Teil des von Spring verwendeten Bean Validation-Frameworks beim Erstellen eines Person-Objekts aus den Feldern im Formular. Folgendes Problem tritt dabei auf. Wenn wir nur @NotBlank im phoneNumber-Feld verwenden, überprüft die App nicht, ob es sich bei der Telefonnummer überhaupt um eine Nummer handelt, geschweige denn eine gültige Telefonnummer.

Für eine bessere Überprüfung können wir die benutzerdefinierte Annotation @ValidPhoneNumber erstellen, die mithilfe der Twilio Lookup-API die Gültigkeit einer Telefonnummer überprüft.

Verbesserte Überprüfung mit der Twilio Lookup-API

Wir müssen zwei neue Klassen erstellen und einige Konfigurationen vornehmen:

  • Eine Annotation mit dem Namen ValidPhoneNumber, die zum Markieren des phoneNumber-Felds in der Person-Klasse verwendet werden kann.
  • Eine Klasse, die ConstraintValidator implementiert. Dieser enthält den Code zum Durchführen der Überprüfung.
  • Unsere Twilio-Kontodetails werden für die Authentifizierung von der Lookup-API benötigt.

Anschließend können wir diese Annotation in der Person-Klasse verwenden.

Erstellen der Annotation

Wir erstellen in demselben Paket, in dem sich die anderen Klassen befinden, eine neue Datei mit dem Namen ValidPhoneNumber.java, die den Code für die Annotation enthält. Annotationen werden mit dem @interface-Schlüsselwort deklariert. Der Code für die Annotation lautet:

@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PhoneNumberValidator.class)
public @interface ValidPhoneNumber {
   String message() default "doesn't seem to be a valid phone number";
   Class<?>[] groups() default {};
   Class<? extends Payload>[] payload() default {};
}

[vollständiger Code, einschließlich Importe, auf GitHub]

Das ist die Standardmethode zum Erstellen einer Annotation für das Bean Validation-Framework. Sie mag zwar etwas kompliziert erscheinen, aber die zwei wichtigsten Stellen sind hier hervorgehoben:

  • die @Constraint-Annotation, die die Klasse angibt, die den Code zum Durchführen der Überprüfung enthält
  • die Standardnachricht, die überschrieben werden kann, wie wir später noch sehen werden

Erstellen der Überprüfung

Wir erstellen die PhoneNumberValidator-Klasse in demselben Paket und fügen den folgenden Inhalt ein:

@Configurable
public class PhoneNumberValidator implements ConstraintValidator<ValidPhoneNumber, String> {

   @Value("${TWILIO_ACCOUNT_SID}")
   private String twilioAccountSid;

   @Value("${TWILIO_AUTH_TOKEN}")
   private String twilioAuthToken;

   @Override
   public void initialize(ValidPhoneNumber constraintAnnotation) {
       Twilio.init(twilioAccountSid, twilioAuthToken);
   }

   @Override
   public boolean isValid(String value, ConstraintValidatorContext context) {

       // The Lookup API requires your phone number in E.164 format
       // E.164 formatted phone numbers must not have spaces in them
       value = value.replaceAll("[\\s()-]", "");

       if ("".equals(value)){
           return false;
       }

       try {
           PhoneNumber.fetcher(new com.twilio.type.PhoneNumber(value)).fetch();
           return true;

       } catch (ApiException e){
           // The Lookup API returns HTTP 404 if the phone number is not found
           // (ie it is not a real phone number)
           if (e.getStatusCode() == 404){
               return false;
           }
           throw e;
       }
   }
}

[vollständiger Code, einschließlich Importe, auf GitHub]

Die isValid-Methode muss true zurückgeben, wenn der Wert eine gültige Telefonnummer ist. Dazu müssen wir allerdings ein paar Schritte ausführen. Zuerst müssen wir von der vom Benutzer eingegebenen Nummer alle nicht erforderlichen Zeichen entfernen:

       // The Lookup API requires your phone number in E.164 format
       // E.164 formatted phone numbers must not have spaces in them
       value = value.replaceAll("[\\s()-]", "");

Für gewöhnlich werden Telefonnummern mit Leerzeichen, Klammern und Bindestrichen geschrieben, um die Zahlen zu gruppieren. Die Lookup-API erwartet allerdings eine Eingabe im E.164-Format. Dabei handelt es sich um ein Standardformat für internationale Telefonnummern, die mit einem + beginnen und nur Zahlen enthalten, keine anderen Leerzeichen oder Sonderzeichen.

Wenn der Benutzer keine Eingabe macht, können wir davon ausgehen, dass es keine gültige Telefonnummer ist. Deshalb brechen wir hier ab, um uns einen API-Aufruf zu sparen. Ein Vergleich mit einer leeren Zeichenfolge ist hier in Ordnung, aber wenn wir Java 11 verwenden würden, wäre String#isBlank() angebracht:

       if ("".equals(value)){
           return false;
       }

Jetzt ist es ist an der Zeit, die Lookup-API aufzurufen. Das erreichen wir mit dem folgenden Code:

           PhoneNumber.fetcher(new com.twilio.type.PhoneNumber(value)).fetch();
           return true;

Wenn die Telefonnummer nicht gültig ist, gibt die Lookup-API eine Fehlermeldung 404 zurück, die im Code als eine ApiException auftaucht. Wenn return true zurückgegeben wird, handelt es sich um eine gültige Telefonnummer. Falls dies nicht der Fall ist, geben wir den catch-Block ein und geben „false“ zurück, wenn der Antwortcode 404 lautet.

Konfigurieren des Twilio-Clients

Wir fügen der App unsere Anmeldeinformationen für das Twilio-Konto hinzu. Dann geben wir die Werte unter src/main/resources/application.properties ein. Diese finden wir in unserer Twilio-Konsole.

TWILIO_ACCOUNT_SID=AC.....
TWILIO_AUTH_TOKEN=......

Diese Werte werden durch Spring zur Laufzeit in den PhoneNumberValidator eingefügt.

Verwenden der Überprüfung

Endlich sind wir soweit, die von uns erstellte Überprüfung einzusetzen. Wir ersetzen in der Person-Klasse:

@NotNull
@NotBlank(message="Please enter your phone number")
private String phoneNumber;

durch

@NotNull
@ValidPhoneNumber(message="Please enter a valid phone number")
private String phoneNumber;

Anhand dieses Vorgangs können wir auch die Standardnachricht für einen Fehler bei der Überprüfung überschreiben.

Testen der Überprüfung

Wir starten unsere Anwendung neu und testen sie noch einmal. Wir beenden den Server, den wir zuvor ausgeführt haben, und führen mit dem Befehl ./mvnw spring-boot:run einen Neustart durch. Jetzt sollten wir nur fortfahren können, indem wir eine gültige Telefonnummer eingeben. Wenn wir uns außerhalb der USA befinden, dürfen wir die internationale Vorwahlnummer nicht vergessen.

Noch einmal die App-UI. Die Telefonnummernüberprüfung funktioniert nun, da „123456789“ zurückgewiesen wird

Zusammenfassung

In diesem Blog haben wir eine Spring Boot-Anwendung mit einer benutzerdefinierten Überprüfung erstellt. Für die Überprüfung haben wir das Bean Validation-Framework verwendet, das die Twilio Lookup-API aufruft, um die Gültigkeit einer Telefonnummer zu überprüfen. Keine leichte Aufgabe, deshalb dürfen wir uns jetzt selbst kurz auf die Schulter klopfen.

Dieser Code prüft natürlich nicht, ob die Telefonnummer auch tatsächlich der Person gehört, die das Formular ausfüllt. Weitere Informationen dazu findest du in der Dokumentation zur Verify-API. Und wenn du mehr dazu erfahren möchtest, wie Twilio bei der Sicherheit helfen kann, sieh dir die Informationen zu Authy an.

Wenn du an einer weiteren Entwicklung mit Twilio und Java interessiert bist, können dir unsere Schnellstarts und die Java-Beiträge in unserem Blog weiterhelfen. Wie immer bin ich gespannt auf deine Ergebnisse. Du findest mich auf Twitter unter @MaximumGilliard oder sende eine E-Mail an mgilliard@twilio.com