Hasła są najsłabszym ogniwem w bezpieczeństwie kont. Mogą być wyłudzane, wyciekać, być ponownie używane lub zapomniane. Dlatego dodaliśmy obsługę WebAuthn Passkeys - odporną na phishing, bezhasłową metodę uwierzytelniania, która jest zarówno bezpieczniejsza, jak i wygodniejsza.

Czym są Passkeys?

Passkeys to poświadczenia kryptograficzne przechowywane na Twoim urządzeniu (telefon, laptop, klucz bezpieczeństwa), które zastępują hasła podczas uwierzytelniania. Wykorzystują standard WebAuthn (część FIDO2) i zapewniają kilka korzyści:

  • Odporne na phishing - Passkeys są powiązane z domeną strony internetowej, więc nie można ich użyć na fałszywych stronach
  • Brak sekretów do wycieku - Na serwerze przechowywany jest tylko klucz publiczny
  • Powiązane z urządzeniem - Klucz prywatny nigdy nie opuszcza Twojego urządzenia
  • Chronione biometrycznie - Zazwyczaj zabezpieczone przez Face ID, Touch ID lub Windows Hello
  • Synchronizacja między urządzeniami - Nowoczesne platformy synchronizują Passkeys między urządzeniami poprzez konta iCloud, Google lub Microsoft

Nasza implementacja

Zintegrowaliśmy obsługę WebAuthn Passkeys z naszym istniejącym stosem uwierzytelniania django-allauth, zapewniając punkty końcowe API zarówno dla wersji webowej, jak i mobilnej.

Przepływ rejestracji

Gdy użytkownik rejestruje nowy Passkey, przepływ działa następująco:

  1. Klient żąda opcji rejestracji od serwera
  2. Serwer generuje wyzwanie z informacjami o użytkowniku i stronie zaufanej
  3. API WebAuthn przeglądarki prosi użytkownika (biometria lub klucz bezpieczeństwa)
  4. Klient wysyła poświadczenie z powrotem do serwera
  5. Serwer weryfikuje i przechowuje klucz publiczny
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# API endpoint to begin registration
class WebAuthnRegistrationOptionsView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        from allauth.mfa.webauthn.internal import auth as webauthn_auth

        # Generate credential creation options
        creation_options = webauthn_auth.begin_registration(
            request.user,
            passwordless=False  # Use as 2FA, not passwordless
        )

        return Response({
            "success": True,
            "creation_options": creation_options,
        })

Przepływ uwierzytelniania

Dla uwierzytelniania dwuskładnikowego z użyciem Passkey:

  1. Użytkownik kończy uwierzytelnianie podstawowe (nazwa użytkownika/hasło lub logowanie społecznościowe)
  2. Serwer zwraca wyzwanie do weryfikacji WebAuthn
  3. Przeglądarka prosi o Passkey (dotyk biometryczny)
  4. Poświadczenie jest weryfikowane względem przechowywanego klucza publicznego
  5. Użytkownik jest w pełni uwierzytelniony
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class WebAuthnVerifyView(APIView):
    def post(self, request):
        credential = request.data.get("credential")

        # Complete authentication and verify credential
        authenticator = webauthn_auth.complete_authentication(
            request.user,
            credential
        )

        # Record usage for security monitoring
        authenticator.last_used_at = timezone.now()
        authenticator.save()

        return Response({"success": True})

Zarządzanie Passkeys

Użytkownicy mogą zarządzać swoimi zarejestrowanymi Passkeys:

  • Lista wszystkich Passkeys z datą rejestracji i ostatniego użycia
  • Zmiana nazwy Passkeys dla łatwiejszej identyfikacji (np. “iPhone”, “MacBook”)
  • Usuwanie Passkeys (z ochroną przed usunięciem ostatniego uwierzytelniacza)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class WebAuthnListView(APIView):
    def get(self, request):
        authenticators = Authenticator.objects.filter(
            user=request.user,
            type=Authenticator.Type.WEBAUTHN
        ).order_by("-created_at")

        return Response({
            "passkeys": [
                {
                    "id": auth.pk,
                    "name": auth.wrap().name,
                    "created_at": auth.created_at.isoformat(),
                    "last_used_at": auth.last_used_at.isoformat() if auth.last_used_at else None,
                }
                for auth in authenticators
            ]
        })

Punkty końcowe API

Nasze REST API zapewnia pełną obsługę WebAuthn dla aplikacji mobilnej:

Punkt końcowyMetodaOpis
/api/webauthn/register/options/GETPobierz wyzwanie rejestracji
/api/webauthn/register/complete/POSTZakończ rejestrację
/api/webauthn/authenticate/options/GETPobierz wyzwanie uwierzytelniania
/api/webauthn/verify/POSTZweryfikuj poświadczenie dla 2FA
/api/webauthn/GETLista zarejestrowanych Passkeys
/api/webauthn/<id>/PATCHZmień nazwę Passkey
/api/webauthn/<id>/DELETEUsuń Passkey

Uwagi dotyczące bezpieczeństwa

Kody odzyskiwania

Gdy użytkownik rejestruje swój pierwszy uwierzytelniacz (Passkey lub TOTP), automatycznie generujemy kody odzyskiwania. Te jednorazowe kody mogą być użyte, jeśli wszystkie inne metody uwierzytelniania staną się niedostępne:

1
2
if Authenticator.objects.filter(user=request.user).count() == 1:
    auto_generate_recovery_codes(request._request)

Zapobieganie blokadzie

Użytkownicy nie mogą usunąć ostatniego Passkey, jeśli pozostawiłoby ich to bez żadnej metody uwierzytelniania dwuskładnikowego:

1
2
3
4
if not adapter.can_delete_authenticator(authenticator):
    return Response({
        "message": "Cannot delete - you must have at least one authentication method"
    }, status=400)

Monitorowanie

Śledzimy użycie Passkeys poprzez metryki Datadog do monitorowania bezpieczeństwa:

1
2
3
increment("webauthn.registration.success")
increment("webauthn.verify.success")
increment("webauthn.verify.failed")

Obsługa przeglądarek

WebAuthn jest obsługiwany we wszystkich nowoczesnych przeglądarkach:

  • Chrome 67+
  • Firefox 60+
  • Safari 13+
  • Edge 79+
  • Mobilny Chrome, Safari, Firefox

Dla starszych przeglądarek użytkownicy mogą nadal używać TOTP (aplikacje uwierzytelniające) lub kodów odzyskiwania.

Doświadczenie użytkownika

Dodanie Passkey zajmuje tylko kilka sekund:

  1. Przejdź do Ustawienia → Bezpieczeństwo → Uwierzytelnianie dwuskładnikowe
  2. Kliknij Dodaj Passkey
  3. Nazwij swoje urządzenie (np. “iPhone 15”)
  4. Uwierzytelnij się za pomocą Face ID / Touch ID / Windows Hello
  5. Gotowe! Twój Passkey jest zarejestrowany

Przyszłe logowania wymagają tylko potwierdzenia biometrycznego - bez wpisywania haseł lub kopiowania kodów z aplikacji uwierzytelniających.

Dlaczego wybraliśmy Passkeys

MetodaRyzyko phishinguDoświadczenie użytkownikaOdzyskiwanie
HasłaWysokieSłabe (zapomniane, słabe)Reset e-mail
SMS 2FAŚrednie (SIM swap)W porządkuNumer telefonu
Aplikacje TOTPNiskieRęczne wprowadzanie koduKlucze zapasowe
PasskeysBardzo niskieDoskonałeKody odzyskiwania

Passkeys reprezentują przyszłość uwierzytelniania. Są już obsługiwane przez platformy Apple, Google i Microsoft, co czyni je dostępnymi dla prawie wszystkich naszych użytkowników.


Gotowy na życie bez haseł? Włącz Passkeys w swoich ustawieniach bezpieczeństwa!