Ein Login-Fehler, der auf eine fehlerhafte Speicherung von Telefonnummern zurückzuführen war, legte eine Schwachstelle offen. Das Konto eines Nutzers wurde gesperrt, weil die Datenbank dieselbe deutsche Mobilfunknummer in zwei verschiedenen Formaten enthielt – 0171 5550134 in einer Zeile und +49 171 5550134 in einer anderen – sodass das System sie als unterschiedliche Einträge behandelte. Das Ergebnis: Ein OTP kam nie an, und der „Code senden“-Button wurde zum Glücksspiel.
Warum Telefonnummern schwieriger sind als Datumsangaben
Entwickler vertrauen oft auf einen Regex, um die Eingabe von Telefonnummern zu bändigen. Dieses Vertrauen zerbricht in dem Moment, in dem eine Nummer eine Grenze überschreitet oder sich ein nationaler Plan ändert. Datumsangaben folgen einem vorhersehbaren Kalender; Telefonnummern verändern sich durch Anbieter, Regulierungen und kulturelle Konventionen.
Die versteckten Kosten von Rohstrings
Eine Telefonnummer als einfachen String zu speichern, scheint sicher zu sein – bis zwei Darstellungen auf dieselbe Leitung verweisen. OTP-Systeme, die die Datenbank nach „der“ Nummer abfragen, senden den Code am Ende an ein Duplikat, das den Nutzer nie erreicht.
Das Problem verschärft sich, wenn Nummern in numerischen Feldern gespeichert werden. Eine BIGINT-Spalte entfernt das führende + sowie alle führenden Nullen und wandelt +49 171 5550134 in 491715550134 um. Ohne das Pluszeichen wird die Rekonstruktion des ursprünglichen Formats zum Ratespiel.
Der E.164-Standard
Der internationale Telefonnummernplan E.164 definiert eine einzige, portable Darstellung:
- Beginnt mit einem
+ - Gefolgt von einer 1- bis 3-stelligen Länderkennung
- Dann die Teilnehmernummer
- Insgesamt nicht mehr als 15 Ziffern
- Keine Leerzeichen, Punkte oder Bindestriche
E.164 garantiert nicht, dass die Nummer aktiv ist; es garantiert lediglich, dass der String einem gültigen Strukturmuster entspricht. Betrachten Sie es als Formatvertrag, nicht als Erreichbarkeits-Orakel.
Häufige Fallstricke, die ein Regex nicht beheben kann
- Numerische Speicherung – BIGINT verwirft das
+und führende Nullen. Verwenden Sie stattdessen eine Textspalte (TEXT oder VARCHAR). - Hardcodierte Regexes – Nationale Pläne ändern sich. Mexiko hat 2019 seine Vorwahl entfernt; Argentinien verlangt für Mobilfunknummern nun eine
9nach der Länderkennung. Ein statisches Muster wird schnell veraltet. - Blinde Nullentfernung – Italienische Festnetzanschlüsse behalten eine führende Null, deutsche nicht. Eine pauschale Regel wie „führende Nullen entfernen“ korrumpiert italienische Daten, während deutsche Nummern unberührt bleiben.
- Annahme, dass das Format die Zustellbarkeit garantiert – libphonenumber validiert die Struktur, kann aber nicht sagen, ob das Endgerät eingeschaltet oder die Nummer portiert wurde.
Aufbau einer zuverlässigen Pipeline
- Nach dem Land fragen – Fügen Sie in Registrierungsformularen eine Länderauswahl hinzu und übergeben Sie diese Region an den Parser.
- Live-Formatierung anzeigen – Nutzen Sie eine „AsYouType“-Formatierung, damit Nutzer das korrekte Muster während der Eingabe sehen.
- Validierung beim Verlassen des Feldes (on blur) – Führen Sie die Validierung durch, nachdem der Nutzer das Feld verlassen hat, anstatt bei jedem Tastendruck; dies reduziert Reibungsverluste.
- Nur den E.164-String speichern – Speichern Sie die normalisierte, mit
+beginnende Nummer in der Datenbank. - Formatierung an der Schnittstelle – Konvertieren Sie die Nummer erst in der Benutzeroberfläche oder in E-Mail-Vorlagen zurück in ein benutzerfreundliches Layout.
Bewahren Sie beim Migrieren von Altdaten die Zeilen auf, die die Validierung nicht bestehen. Parsen Sie jeden bestehenden Eintrag in eine neue Spalte, markieren Sie die Fehler und erstellen Sie einen Bericht. Das stille Verwerfen von Daten führt zu Support-Tickets, die später teure Fehlerbehebungen nach sich ziehen.
Eine kurze Checkliste für Entwickler
- Speichern Sie Nummern als TEXT/VARCHAR im E.164-Format.
- Nutzen Sie Googles libphonenumber-Bibliothek; sie bewältigt die komplexe Realität globaler Pläne.
- Geben Sie eine Standardregion für Nutzer an, die die Länderkennung weglassen.
- Rufen Sie
is_valid_numberfür Live-Registrierungen auf; dies prüft, ob die Nummer den regionalen Regeln entspricht. - Verwenden Sie
is_possible_numberbeim Bereinigen von Massendaten; dies erkennt offensichtlich fehlerhafte Einträge, ohne Grenzfälle abzulehnen.
Eine ordnungsgemäße Handhabung von Telefonnummern ist kein „Nice-to-have“, sondern eine Grundvoraussetzung für jedes System, das auf eine zuverlässige Nutzerkontaktaufnahme angewiesen ist. Durch die Normalisierung auf E.164 und die Auslagerung des Parsings an eine bewährte Bibliothek eliminieren Entwickler eine ganze Klasse von Fehlern, die stillschweigend Vertrauen und Umsatz untergraben. Behandeln Sie Telefonnummern als strukturierte Daten, nicht als Freitext, und überlassen Sie die schwere Arbeit den Standards.
