As palavras-passe são o elo mais fraco na segurança das contas. Podem ser alvo de phishing, vazadas, reutilizadas ou esquecidas. Por isso, adicionámos suporte para Passkeys WebAuthn - um método de autenticação sem palavra-passe resistente a phishing, mais seguro e mais conveniente.

O que são Passkeys?

Passkeys são credenciais criptográficas armazenadas no seu dispositivo (telemóvel, portátil, chave de segurança) que substituem as palavras-passe para autenticação. Utilizam a norma WebAuthn (parte do FIDO2) e oferecem várias vantagens:

  • Resistentes a phishing - As Passkeys estão ligadas ao domínio do website, por isso não podem ser usadas em sites falsos
  • Sem segredos para vazar - Apenas a chave pública é armazenada no servidor
  • Ligadas ao dispositivo - A chave privada nunca sai do seu dispositivo
  • Protegidas por biometria - Tipicamente protegidas por Face ID, Touch ID ou Windows Hello
  • Sincronização entre dispositivos - As plataformas modernas sincronizam Passkeys entre dispositivos através de contas iCloud, Google ou Microsoft

A nossa implementação

Integrámos o suporte para Passkeys WebAuthn na nossa pilha de autenticação django-allauth existente, fornecendo endpoints API tanto para web como para dispositivos móveis.

Fluxo de registo

Quando um utilizador regista uma nova Passkey, o fluxo funciona assim:

  1. O cliente solicita opções de registo ao servidor
  2. O servidor gera um desafio com informações do utilizador e da relying party
  3. A API WebAuthn do navegador solicita ao utilizador (biometria ou chave de segurança)
  4. O cliente envia a credencial de volta ao servidor
  5. O servidor verifica e armazena a chave pública
 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,
        })

Fluxo de autenticação

Para autenticação de dois fatores usando uma Passkey:

  1. O utilizador completa a autenticação primária (nome de utilizador/palavra-passe ou login social)
  2. O servidor devolve um desafio para verificação WebAuthn
  3. O navegador solicita a Passkey (toque biométrico)
  4. A credencial é verificada contra a chave pública armazenada
  5. O utilizador está totalmente autenticado
 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})

Gestão de Passkeys

Os utilizadores podem gerir as suas Passkeys registadas:

  • Listar todas as Passkeys com data de registo e última utilização
  • Renomear Passkeys para identificação mais fácil (ex., “iPhone”, “MacBook”)
  • Eliminar Passkeys (com proteção contra remoção do último autenticador)
 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
            ]
        })

Endpoints da API

A nossa REST API fornece suporte completo para WebAuthn para a aplicação móvel:

EndpointMétodoDescrição
/api/webauthn/register/options/GETObter desafio de registo
/api/webauthn/register/complete/POSTCompletar registo
/api/webauthn/authenticate/options/GETObter desafio de autenticação
/api/webauthn/verify/POSTVerificar credencial para 2FA
/api/webauthn/GETListar Passkeys registadas
/api/webauthn/<id>/PATCHRenomear uma Passkey
/api/webauthn/<id>/DELETEEliminar uma Passkey

Considerações de segurança

Códigos de recuperação

Quando um utilizador regista o seu primeiro autenticador (Passkey ou TOTP), geramos automaticamente códigos de recuperação. Estes códigos de uso único podem ser utilizados se todos os outros métodos de autenticação ficarem indisponíveis:

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

Prevenção de bloqueio

Os utilizadores não podem eliminar a sua última Passkey se isso os deixar sem qualquer método de autenticação de dois fatores:

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)

Monitorização

Rastreamos a utilização de Passkeys através de métricas Datadog para monitorização de segurança:

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

Suporte de navegadores

WebAuthn é suportado em todos os navegadores modernos:

  • Chrome 67+
  • Firefox 60+
  • Safari 13+
  • Edge 79+
  • Chrome móvel, Safari, Firefox

Para navegadores mais antigos, os utilizadores podem continuar a usar TOTP (aplicações de autenticação) ou códigos de recuperação.

A experiência do utilizador

Adicionar uma Passkey demora apenas segundos:

  1. Vá a Definições → Segurança → Autenticação de dois fatores
  2. Clique em Adicionar Passkey
  3. Nomeie o seu dispositivo (ex., “iPhone 15”)
  4. Autentique-se com Face ID / Touch ID / Windows Hello
  5. Pronto! A sua Passkey está registada

Os logins futuros requerem apenas uma confirmação biométrica - sem escrever palavras-passe ou copiar códigos de aplicações de autenticação.

Porquê escolhemos Passkeys

MétodoRisco de phishingExperiência do utilizadorRecuperação
Palavras-passeAltoFraca (esquecidas, fracas)Reset por email
SMS 2FAMédio (SIM swap)RazoávelNúmero de telefone
Apps TOTPBaixoEntrada manual de códigoChaves de backup
PasskeysMuito baixoExcelenteCódigos de recuperação

As Passkeys representam o futuro da autenticação. Já são suportadas pelas plataformas Apple, Google e Microsoft, tornando-as acessíveis a quase todos os nossos utilizadores.


Pronto para dispensar as palavras-passe? Ative as Passkeys nas suas definições de segurança!