diff --git a/CROSS_DEVICE_PROBLEM_ZUSAMMENFASSUNG.md b/CROSS_DEVICE_PROBLEM_ZUSAMMENFASSUNG.md new file mode 100644 index 0000000..479587d --- /dev/null +++ b/CROSS_DEVICE_PROBLEM_ZUSAMMENFASSUNG.md @@ -0,0 +1,151 @@ +# Cross-Device Passkey Problem - Zusammenfassung + +## Aktueller Status + +✅ **Was funktioniert:** +- CORS ist korrekt konfiguriert (OPTIONS gibt 204 zurück) +- POST-Requests funktionieren (Status 200) +- Options werden korrekt generiert +- QR-Code wird angezeigt (Desktop-Browser) +- Website öffnet sich auf dem Smartphone nach QR-Code-Scan + +❌ **Was nicht funktioniert:** +- Verbindung vom Smartphone zum Server wird nicht hergestellt +- "Verbindung mit einem anderen Gerät wird hergestellt" bleibt hängen +- Keine Requests vom Smartphone im Server-Log +- Warnung: "startRegistration() was not called correctly" + +## Mögliche Ursachen + +### 1. WebAuthn API auf dem Smartphone +**Problem:** Die WebAuthn-API auf dem Smartphone kann die Verbindung nicht herstellen. + +**Prüfung:** +- Öffne die Website direkt auf dem Smartphone: `https://harheimertc.tsschulz.de/registrieren` +- Versuche, einen Passkey zu registrieren (ohne QR-Code) +- Funktioniert das? + +### 2. QR-Code-Inhalt +**Problem:** Der QR-Code enthält möglicherweise nicht die richtige URL oder Challenge. + +**Prüfung:** +- Scanne den QR-Code mit einem QR-Code-Scanner +- Prüfe, welche URL/Informationen im QR-Code enthalten sind +- Sollte die Origin `https://harheimertc.tsschulz.de` enthalten + +### 3. Browser-Kompatibilität +**Problem:** Nicht alle Browser unterstützen Cross-Device Passkeys gleich gut. + +**Prüfung:** +- Welcher Browser wird auf dem Desktop verwendet? (Chrome, Firefox, Edge, Safari) +- Welcher Browser wird auf dem Smartphone verwendet? +- Chrome/Edge sollten am besten funktionieren + +### 4. Netzwerk/Firewall +**Problem:** Das Smartphone kann die Server-Origin nicht erreichen (obwohl die Website funktioniert). + +**Prüfung:** +- Kann das Smartphone die Website direkt öffnen? ✅ (bereits bestätigt) +- Kommen OPTIONS-Requests vom Smartphone an? (Test-Seite zeigt: ✅) +- Kommen POST-Requests vom Smartphone an? (Test-Seite zeigt: ✅) + +### 5. Options-Struktur +**Problem:** Die Warnung "startRegistration() was not called correctly" deutet auf ein Problem mit der Options-Struktur hin. + +**Prüfung:** +- Prüfe Browser-Konsole (Desktop) auf die Debug-Logs +- Prüfe, ob die Options-Struktur korrekt ist +- Die Options sollten direkt von `@simplewebauthn/server` kommen (keine manuelle Serialisierung) + +## Debugging-Schritte + +### Schritt 1: Server-Logs prüfen +```bash +pm2 logs harheimertc --lines 200 | grep -i "register-passkey\|mobile\|smartphone\|user-agent" +``` + +**Was zu prüfen ist:** +- Kommt ein Request vom Smartphone an, wenn der QR-Code gescannt wird? +- Welcher User-Agent? (Sollte "Mobile", "iPhone", "Android" enthalten) +- Welche IP-Adresse? (Sollte die IP des Smartphones sein) + +### Schritt 2: Browser-Konsole prüfen (Desktop) +**Öffne F12 → Console und prüfe:** +- Gibt es die Warnung "startRegistration() was not called correctly"? +- Was zeigen die Debug-Logs `[DEBUG] Full options structure check`? +- Wird der QR-Code angezeigt? + +### Schritt 3: Smartphone direkt testen +**Öffne auf dem Smartphone:** +``` +https://harheimertc.tsschulz.de/registrieren +``` + +**Versuche:** +- Registrierung mit Passkey (ohne QR-Code) +- Funktioniert das? (Sollte einen lokalen Authenticator verwenden) + +### Schritt 4: QR-Code-Inhalt prüfen +**Scanne den QR-Code mit einem QR-Code-Scanner:** +- Welche URL/Informationen sind enthalten? +- Enthält er die richtige Origin? +- Enthält er die Challenge? + +## Bekannte Probleme + +### Problem 1: "startRegistration() was not called correctly" +**Ursache:** Die Options-Struktur ist nicht korrekt. + +**Lösung:** +- Options werden jetzt direkt von `@simplewebauthn/server` zurückgegeben (keine manuelle Serialisierung) +- Prüfe Browser-Konsole auf die Debug-Logs + +### Problem 2: Keine Requests vom Smartphone +**Ursache:** Cross-Device-Verbindung funktioniert nicht. + +**Mögliche Lösungen:** +1. Prüfe, ob beide Geräte im gleichen Netzwerk sind +2. Prüfe, ob der Browser Cross-Device unterstützt (Chrome/Edge am besten) +3. Prüfe, ob es Firewall-Blockierungen gibt +4. Versuche einen anderen Browser + +### Problem 3: Timeout +**Ursache:** Die Verbindung wird nicht innerhalb von 5 Minuten hergestellt. + +**Lösung:** +- Prüfe, ob Requests ankommen +- Prüfe, ob CORS korrekt ist (✅ bereits bestätigt) +- Prüfe, ob die Origin übereinstimmt + +## Nächste Schritte + +1. **Prüfe Server-Logs** während des QR-Code-Scans: + - Kommt ein Request an? + - Welcher User-Agent? + - Welche Fehlermeldungen? + +2. **Prüfe Browser-Konsole** (Desktop): + - Gibt es noch die Warnung? + - Was zeigen die Debug-Logs? + +3. **Teste direkt auf dem Smartphone:** + - Öffne die Registrierungsseite + - Versuche, einen Passkey zu registrieren (ohne QR-Code) + - Funktioniert das? + +4. **Teile die Ergebnisse:** + - Server-Logs + - Browser-Konsole (Desktop) + - Was passiert auf dem Smartphone? + +## Wichtige Erkenntnisse + +- ✅ CORS funktioniert (OPTIONS gibt 204 zurück) +- ✅ POST-Requests funktionieren (Status 200) +- ✅ Options werden korrekt generiert +- ✅ QR-Code wird angezeigt +- ✅ Website öffnet sich auf dem Smartphone +- ❌ Verbindung vom Smartphone zum Server wird nicht hergestellt +- ❌ Keine Requests vom Smartphone im Server-Log + +**Das Problem liegt wahrscheinlich in der Cross-Device-Verbindung selbst, nicht in CORS oder der Server-Konfiguration.** diff --git a/server/api/auth/register-passkey-options.post.js b/server/api/auth/register-passkey-options.post.js index 7381ca6..dc37d41 100644 --- a/server/api/auth/register-passkey-options.post.js +++ b/server/api/auth/register-passkey-options.post.js @@ -145,18 +145,43 @@ export default defineEventHandler(async (event) => { // Options direkt zurückgeben (wie in passkeys/registration-options.post.js) // @simplewebauthn/server gibt bereits korrekt formatierte Options zurück const totalDuration = Date.now() - requestStart + + // Debug: Prüfe die vollständige Options-Struktur console.log(`[DEBUG] Returning options (total: ${totalDuration}ms)`, { registrationId, optionsKeys: Object.keys(options), challengeLength: options.challenge?.length, challengeType: typeof options.challenge, rpId: options.rp?.id, + rpName: options.rp?.name, userIdType: typeof options.user?.id, - timeout: options.timeout + userName: options.user?.name, + userDisplayName: options.user?.displayName, + timeout: options.timeout, + timeoutType: typeof options.timeout, + pubKeyCredParamsCount: options.pubKeyCredParams?.length, + authenticatorSelection: options.authenticatorSelection, + hasExtensions: !!options.extensions, + hasHints: !!options.hints, + excludeCredentialsCount: options.excludeCredentials?.length || 0 }) + + // WICHTIG: Prüfe, ob die Options für Cross-Device korrekt sind + // Für Cross-Device muss die Challenge ein String sein (Base64URL) + if (typeof options.challenge !== 'string') { + console.error('[DEBUG] ERROR: Challenge is not a string!', typeof options.challenge, options.challenge) + } + + // Prüfe, ob user.id ein Uint8Array ist (wird zu Base64URL konvertiert) + if (options.user?.id instanceof Uint8Array) { + console.log('[DEBUG] user.id is Uint8Array (will be converted to Base64URL by browser)') + } else { + console.log('[DEBUG] user.id type:', typeof options.user?.id, 'value:', options.user?.id?.substring?.(0, 20)) + } // WICHTIG: Options direkt zurückgeben, keine manuelle Serialisierung // Die Options von @simplewebauthn/server sind bereits korrekt formatiert + // Nuxt/Nitro serialisiert automatisch zu JSON return { success: true, registrationId, options } })