Wachtwoorden zijn de zwakste schakel in accountbeveiliging. Ze kunnen worden gephisht, gelekt, hergebruikt of vergeten. Daarom hebben we ondersteuning toegevoegd voor WebAuthn Passkeys - een phishing-resistente, wachtwoordloze authenticatiemethode die zowel veiliger als handiger is.

Wat zijn Passkeys?

Passkeys zijn cryptografische inloggegevens die zijn opgeslagen op uw apparaat (telefoon, laptop, beveiligingssleutel) en die wachtwoorden vervangen voor authenticatie. Ze gebruiken de WebAuthn-standaard (onderdeel van FIDO2) en bieden verschillende voordelen:

  • Phishing-resistent - Passkeys zijn gebonden aan het domein van de website, dus ze kunnen niet op valse sites worden gebruikt
  • Geen geheimen om te lekken - Alleen de publieke sleutel wordt op de server opgeslagen
  • Apparaatgebonden - De privésleutel verlaat nooit uw apparaat
  • Biometrisch beschermd - Doorgaans beveiligd door Face ID, Touch ID of Windows Hello
  • Cross-device synchronisatie - Moderne platforms synchroniseren Passkeys tussen apparaten via iCloud-, Google- of Microsoft-accounts

Onze implementatie

We hebben WebAuthn Passkeys-ondersteuning geïntegreerd in onze bestaande django-allauth authenticatiestack, met zowel web- als mobiele API-eindpunten.

Registratiestroom

Wanneer een gebruiker een nieuwe Passkey registreert, werkt de stroom als volgt:

  1. Client vraagt registratieopties aan de server
  2. Server genereert een uitdaging met gebruikers- en relying party-informatie
  3. Browser’s WebAuthn API vraagt de gebruiker (biometrie of beveiligingssleutel)
  4. Client stuurt inloggegevens terug naar de server
  5. Server verifieert en slaat de publieke sleutel op
 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,
        })

Authenticatiestroom

Voor tweefactorauthenticatie met een Passkey:

  1. Gebruiker voltooit primaire authenticatie (gebruikersnaam/wachtwoord of sociale login)
  2. Server retourneert uitdaging voor WebAuthn-verificatie
  3. Browser vraagt om Passkey (biometrische aanraking)
  4. Inloggegevens worden geverifieerd tegen de opgeslagen publieke sleutel
  5. Gebruiker is volledig geauthenticeerd
 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})

Passkey-beheer

Gebruikers kunnen hun geregistreerde Passkeys beheren:

  • Alle Passkeys weergeven met registratiedatum en laatste gebruik
  • Passkeys hernoemen voor eenvoudigere identificatie (bijv. “iPhone”, “MacBook”)
  • Passkeys verwijderen (met bescherming tegen het verwijderen van de laatste authenticator)
 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
            ]
        })

API-eindpunten

Onze REST API biedt volledige WebAuthn-ondersteuning voor de mobiele app:

EindpuntMethodeBeschrijving
/api/webauthn/register/options/GETRegistratie-uitdaging ophalen
/api/webauthn/register/complete/POSTRegistratie voltooien
/api/webauthn/authenticate/options/GETAuthenticatie-uitdaging ophalen
/api/webauthn/verify/POSTInloggegevens verifiëren voor 2FA
/api/webauthn/GETGeregistreerde Passkeys weergeven
/api/webauthn/<id>/PATCHEen Passkey hernoemen
/api/webauthn/<id>/DELETEEen Passkey verwijderen

Beveiligingsoverwegingen

Herstelcodes

Wanneer een gebruiker zijn eerste authenticator registreert (Passkey of TOTP), genereren we automatisch herstelcodes. Deze eenmalige codes kunnen worden gebruikt als alle andere authenticatiemethoden niet beschikbaar zijn:

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

Uitsluiting voorkomen

Gebruikers kunnen hun laatste Passkey niet verwijderen als dit hen zonder tweefactorauthenticatiemethode zou achterlaten:

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)

Monitoring

We volgen Passkey-gebruik via Datadog-metrics voor beveiligingsmonitoring:

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

Browserondersteuning

WebAuthn wordt ondersteund in alle moderne browsers:

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

Voor oudere browsers kunnen gebruikers nog steeds TOTP (authenticator-apps) of herstelcodes gebruiken.

De gebruikerservaring

Een Passkey toevoegen duurt slechts enkele seconden:

  1. Ga naar Instellingen → Beveiliging → Tweefactorauthenticatie
  2. Klik op Passkey toevoegen
  3. Geef uw apparaat een naam (bijv. “iPhone 15”)
  4. Authenticeer met Face ID / Touch ID / Windows Hello
  5. Klaar! Uw Passkey is geregistreerd

Toekomstige logins vereisen slechts een biometrische bevestiging - geen wachtwoorden typen of codes kopiëren uit authenticator-apps.

Waarom we voor Passkeys hebben gekozen

MethodePhishing-risicoGebruikerservaringHerstel
WachtwoordenHoogSlecht (vergeten, zwak)E-mail reset
SMS 2FAGemiddeld (SIM-swap)OkéTelefoonnummer
TOTP-appsLaagHandmatige code-invoerBack-upsleutels
PasskeysZeer laagUitstekendHerstelcodes

Passkeys vertegenwoordigen de toekomst van authenticatie. Ze worden al ondersteund door Apple-, Google- en Microsoft-platforms, waardoor ze toegankelijk zijn voor bijna al onze gebruikers.


Klaar om wachtwoordloos te gaan? Activeer Passkeys in uw beveiligingsinstellingen!