QR-Code-Authentifizierung: Das WhatsApp Web-Muster mit Supabase
Um die Website mit der mobilen App zu verbinden, wollte ich etwas Instantanes. Keine Formulare, keine Passwörter zum erneuten Eingeben. Das WhatsApp Web-Muster: einen QR-Code scannen und boom, verbunden. Hier ist, wie ich dieses System in TAMSIV mit Supabase Realtime, einem Fallback-Polling und einer beeindruckenden UX implementiert habe.
Wichtige Punkte zum Merken:
- Der QR-Code kodiert eine eindeutige Sitzungs-UUID – die Website abonniert sich in Echtzeit über Supabase Realtime.
- Ein Fallback-HTTP-Polling (alle 2s) übernimmt, wenn Realtime nach 3 Sekunden fehlschlägt.
- Der QR-Code läuft nach 5 Minuten ab und wird automatisch nach 4min30 mit einem visuellen Countdown neu generiert.
- Das gesamte System besteht aus 300 Zeilen auf der Web-Seite und 150 auf der mobilen Seite.
Warum die Authentifizierung per QR-Code anstelle eines klassischen Formulars wählen?
Die klassische Authentifizierung – E-Mail + Passwort – funktioniert. Aber sie erzeugt Reibung. Der Benutzer hat bereits ein Konto in der mobilen App. Ihn zu bitten, seine Anmeldedaten im Web erneut einzugeben, zwingt ihn, sich an ein Passwort zu erinnern, möglicherweise in seinem Manager zu suchen und ein Scheitern zu riskieren.
Der QR-Code eliminiert diese Reibung. Der Benutzer ist bereits auf seinem Telefon authentifiziert. Das Scannen eines Codes dauert 2 Sekunden. Dies ist das Muster, das von WhatsApp Web, Telegram und Discord populär gemacht wurde. Benutzer kennen und erwarten es.
Für TAMSIV ist dies umso relevanter, da die Website als Ergänzung zur mobilen App dient – nicht als Ersatz. Der QR-Code materialisiert diese Verbindung zwischen den beiden Plattformen.
Wie funktioniert der QR-Code-Authentifizierungsfluss?
Aus Sicht des Benutzers ist es magisch: Ich scanne, ich bin verbunden. Aus technischer Sicht ist es ein präzises Ballett aus Tokens und Echtzeitkanälen. Hier sind die Schritte:
- Generierung: Der Benutzer öffnet tamsiv.com. Die Website generiert eine eindeutige Sitzungs-UUID und erstellt einen Eintrag in Supabase mit dem Status "pending".
- Anzeige: Der QR-Code kodiert diese UUID. Die Website abonniert den Supabase Realtime-Kanal für diese Sitzung.
- Scan: Der Benutzer scannt den QR-Code mit der mobilen TAMSIV-App. Die App dekodiert die UUID.
- Bestätigung: Die App sendet ihr vorhandenes JWT + die UUID an das Backend. Das Backend überprüft das JWT, generiert ein Web-Auth-Token und aktualisiert die Sitzung auf "confirmed".
- Verbindung: Die Website empfängt die Aktualisierung über Realtime, ruft das Token ab, und der Benutzer ist verbunden.
Dieser Fluss stellt sicher, dass nur ein bereits in der mobilen App authentifizierter Benutzer die Sitzung bestätigen kann. Das für das Web generierte Token hat eine begrenzte Lebensdauer und ist unabhängig vom mobilen Token – die beiden Sitzungen sind getrennt.
Wie ermöglicht Supabase Realtime die sofortige Verbindung?
Supabase Realtime ist die Komponente, die das Erlebnis sofort macht. Wenn die mobile App die Sitzung bestätigt, wird die Änderung in der Datenbank vom Realtime-Kanal erkannt und an den Browser gesendet – in wenigen Millisekunden.
Technisch abonniert sich die Website einen spezifischen Kanal, der nach der Sitzungs-UUID filtert:
supabase.channel('qr-auth-SESSION_UUID')
.on('postgres_changes', { event: 'UPDATE', filter: `id=eq.SESSION_UUID` }, callback)
.subscribe()
Der Callback wird ausgelöst, sobald der Status von "pending" auf "confirmed" wechselt. Das Auth-Token ist in der Aktualisierung enthalten. Der Benutzer sieht, wie sich die Anmeldeseite in das Dashboard verwandelt – ohne weitere Aktion.
Es ist derselbe Realtime-Mechanismus, den ich für den Inhaltscache und Live-Updates in den kollaborativen Gruppen verwende.
Warum ist ein Fallback-Polling unerlässlich?
Supabase Realtime funktioniert in den meisten Fällen sehr gut. Aber "die meisten" reichen für eine Authentifizierungsfunktion nicht aus. Einige Unternehmensnetzwerke blockieren WebSockets. Einige Proxys unterbrechen sie. Einige Browser haben spezifische Fehler.
Ich habe ein Fallback-HTTP-Polling implementiert, das automatisch übernimmt:
- Die Website versucht die Realtime-Verbindung für 3 Sekunden
- Wenn die Verbindung fehlschlägt, wechselt sie stillschweigend zu einem HTTP-Polling alle 2 Sekunden
- Das Polling fragt direkt die Datenbank ab: "Ist die Sitzungs-UUID bestätigt?"
- Der Benutzer weiß nie, welcher Mechanismus verwendet wird – das Erlebnis ist identisch
Die 3-Sekunden-Verzögerung ist ein Kompromiss zwischen Reaktivität und Zuverlässigkeit. Kürzer, und wir würden zu schnell zum Polling übergehen (weniger effizient). Länger, und der Benutzer würde ohne Feedback warten.
Dieses duale Muster (Realtime + Polling) ist eine bewährte Methode für jede kritische Funktionalität. Verlasse dich niemals auf einen einzigen Kommunikationskanal.
Wie sichert man das QR-Code-System?
Die QR-Code-Authentifizierung führt spezifische Angriffsvektoren ein. Hier sind die in TAMSIV implementierten Maßnahmen:
- Ablauf nach 5 Minuten: Ein unbenutzter QR-Code wird ungültig. Dies verhindert die Wiederverwendung von Screenshots oder geteilten QR-Codes.
- Einmalige Verwendung: Eine Sitzung kann nur einmal bestätigt werden. Jeder nachfolgende Versuch wird abgelehnt.
- Auth auf mobiler Seite erforderlich: Nur ein in der App angemeldeter Benutzer kann bestätigen. Das JWT wird serverseitig wie bei den WebSockets überprüft.
- Ephemeres Token: Das für das Web generierte Token ist einmalig verwendbar und hat eine begrenzte Lebensdauer. Es dient nur dazu, die Websitzung zu initiieren, nicht als permanentes Token.
- Unvorhersehbare UUID v4: Die für die Sitzung verwendete UUID wird mit einem CSPRNG (Cryptographically Secure Pseudo-Random Number Generator) generiert. Unmöglich zu erraten.
Diese Maßnahmen stimmen mit den OWASP-Empfehlungen für die Authentifizierung überein.
Wie ist das endgültige Benutzererlebnis?
Die UX wurde bis ins kleinste Detail gepflegt:
- Automatische QR-Regenerierung: Nach 4min30 wird der QR-Code automatisch mit einer neuen UUID neu generiert. Ein visueller Countdown zeigt die verbleibende Zeit an. Der Benutzer muss die Seite nie aktualisieren.
- Verbindungsanimation: Wenn der Scan bestätigt wird, wechselt eine flüssige Animation zwischen der Anmeldeseite und dem Dashboard. Kein Neuladen der Seite.
- Alternative Optionen: E-Mail/Passwort und Magic Link sind unter dem QR-Code verfügbar. Kein Benutzer wird blockiert, wenn der Scan nicht funktioniert.
- Responsive: Auf Mobilgeräten (wo der QR keinen Sinn macht) bevorzugt die Oberfläche E-Mail/Passwort und Magic Link. Der QR wird nur auf Desktop/Tablet angezeigt.
Das Onboarding-System führt neue Web-Benutzer zuerst zum QR-Code, mit einem natürlichen Fallback zu den klassischen Methoden.
Wie viel Code repräsentiert diese Funktion?
Etwa 300 Zeilen auf der Web-Seite (QR-Komponente, Realtime/Polling-Logik, Token-Verwaltung) und 150 Zeilen auf der mobilen Seite (Scanner, Verifizierung, API-Aufruf zur Bestätigung). Das ist kompakt.
Der Grund: Supabase erledigt den Großteil der Arbeit. Die Datenbank speichert die Sitzungen, Realtime pusht die Updates, Auth verwaltet die Tokens. Der Anwendungscode konzentriert sich auf die Orchestrierung und die UX.
Dies ist typisch für den Supabase-Architekturansatz von TAMSIV: Maximierung dessen, was die Plattform nativ bietet, Minimierung des benutzerdefinierten Codes. Das gleiche Prinzip, das die Internationalisierungsstrategie und das Gamification-System leitet.
Welche Alternativen zum QR-Code gibt es für die Cross-Device-Authentifizierung?
Andere Ansätze für die Cross-Device-Authentifizierung sind möglich:
- Deep Links: Senden eines anklickbaren Links an den Benutzer, der die App öffnet und bestätigt. Funktioniert gut, erfordert aber, dass der Benutzer auf demselben Gerät ist – was hier nicht der Fall ist.
- Numerischer Code: Anzeigen eines 6-stelligen Codes, den der Benutzer in die App eingibt. Universeller, aber langsamer (6 Sekunden vs. 2 Sekunden für einen Scan).
- Push-Benachrichtigung: Senden einer Push-Benachrichtigung mit einem "Bestätigen"-Button. Erfordert, dass Benachrichtigungen aktiviert sind und das FCM-System konfiguriert ist.
- WebAuthn/Passkeys: Die moderne Lösung, aber noch nicht universell auf allen Geräten unterstützt.
Der QR-Code bietet den besten Kompromiss zwischen Geschwindigkeit, Universalität und "Wow-Effekt". Es ist die Art von Funktion, die dazu führt, dass man sagt "das ist gut durchdacht" – und genau diesen Eindruck möchte TAMSIV hinterlassen.
FAQ
Was passiert, wenn ich den Browser schließe, nachdem ich den QR-Code gescannt habe?
Das für die Websitzung generierte Token wird im lokalen Speicher abgelegt. Beim nächsten Besuch überprüft die Website dieses Token und meldet dich automatisch wieder an, wenn das Token noch gültig ist. Du musst den QR-Code nicht bei jedem Besuch erneut scannen.
Kann man mehrere Websitzungen gleichzeitig haben?
Ja, jeder Scan erstellt eine unabhängige Sitzung. Du kannst gleichzeitig auf deinem Desktop-Computer und deinem Laptop angemeldet sein. Jede Sitzung hat ihr eigenes Token und kann individuell über die App-Einstellungen widerrufen werden.
Funktioniert der QR-Code ohne Internetverbindung?
Nein, der QR-Code erfordert eine aktive Internetverbindung auf beiden Seiten (mobil und Web). Der Scan dekodiert eine UUID, die online über Supabase überprüft werden muss. Für die Offline-Nutzung bleiben die E-Mail-/Passwort-Methoden verfügbar.
Wie schützt TAMSIV vor QR-Code-Phishing?
Der QR-Code kodiert nur eine Sitzungs-UUID – keine sensiblen Daten. Die Bestätigung erfolgt über die offizielle TAMSIV-App, die die Domain und die Gültigkeit der Sitzung überprüft. Ein gefälschter QR-Code würde auf eine nicht existierende UUID in der Datenbank umleiten und sofort fehlschlagen.
Warum läuft der QR-Code nur nach 5 Minuten ab?
Fünf Minuten sind ein Kompromiss zwischen Sicherheit und UX. Es ist lang genug, damit der Benutzer Zeit hat, sein Telefon zu nehmen und zu scannen. Es ist kurz genug, um das Angriffsfenster zu begrenzen, falls der QR abgefangen wird. Die automatische Regeneration nach 4min30 garantiert einen immer frischen QR ohne Zutun des Benutzers.