Skip to main content

Verificar autenticación WebAuthn

Endpoint: POST /auth/webauthn/authentication/verify


Verifica una respuesta de autenticación WebAuthn/FIDO2 y, si es válida, proporciona un token JWT para acceso autenticado.


📝 Cuerpo de la solicitud

{
"email": "usuario@ejemplo.com",
"credential": {
"id": "credential-id",
"rawId": "raw-credential-id",
"response": {
"authenticatorData": "authenticator-data-base64",
"clientDataJSON": "client-data-json-base64",
"signature": "signature-base64"
},
"type": "public-key"
}
}

Parámetros:

  • email: Correo electrónico del usuario que se autentica
  • credential: Objeto credencial generado por navigator.credentials.get()

📋 Respuestas

✅ 200 OK

  • Autenticación exitosa

    {
    "verified": true,
    "accessToken": "jwt-token-string",
    "user": {
    "id": "user-id",
    "email": "usuario@ejemplo.com",
    "verified": true
    },
    "credentialUsed": {
    "id": "credential-id",
    "name": "YubiKey de Juan",
    "lastUsed": "2025-01-20T14:45:00.000Z"
    }
    }

❌ 400 Bad Request

  • Credencial inválida

    {
    "verified": false,
    "error": "Invalid credential signature"
    }
  • Challenge expirado o inválido

    {
    "verified": false,
    "error": "Invalid or expired challenge"
    }
  • Usuario no encontrado

    {
    "verified": false,
    "error": "User not found"
    }
  • Credencial no registrada

    {
    "verified": false,
    "error": "Credential not registered for this user"
    }

🔍 Proceso de verificación

Validaciones realizadas

  1. Challenge: Verifica que el challenge coincida con el generado para autenticación
  2. Firma: Valida la firma criptográfica usando la clave pública almacenada
  3. Contador: Verifica el contador de uso para detectar credenciales clonadas
  4. Origen: Confirma que la autenticación fue realizada para el dominio correcto
  5. Usuario: Verifica que la credencial pertenece al usuario especificado

Datos actualizados

  • Último uso: Se actualiza la fecha de último uso de la credencial
  • Contador: Se incrementa el contador de uso
  • Logs: Se registra la autenticación exitosa para auditoría

💻 Ejemplo de implementación frontend

// Después de obtener options de /auth/webauthn/authentication/options
const credential = await navigator.credentials.get({
publicKey: options
});

// Verificar autenticación
const verifyResponse = await fetch('/auth/webauthn/authentication/verify', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: 'usuario@ejemplo.com',
credential: credential
})
});

const result = await verifyResponse.json();
if (result.verified) {
// Guardar token JWT
localStorage.setItem('token', result.accessToken);
// Redirigir a área autenticada
}

🛡️ Características de seguridad

Detección de clonación

  • Verificación de contador incremental
  • Detección de uso simultáneo de credenciales

Validación criptográfica

  • Verificación de firma digital
  • Validación de autenticador y cliente

Auditoría completa

  • Registro de todos los intentos de autenticación
  • Tracking de credenciales utilizadas
  • Logs de seguridad detallados

📊 Información del token JWT

El token JWT generado incluye:

  • ID de usuario: Para identificación en requests posteriores
  • Roles y permisos: Según la configuración del usuario
  • Expiración: Tiempo de vida del token
  • Metadata: Información sobre el método de autenticación utilizado

📝 Notas

  • La credencial debe haber sido obtenida usando opciones de /auth/webauthn/authentication/options
  • Una autenticación exitosa proporciona acceso completo como cualquier login tradicional
  • Se actualiza automáticamente la información de último uso de la credencial
  • Compatible con todos los flujos de autenticación existentes (2FA, verificaciones adicionales, etc.)

🔗 Endpoints relacionados


⚡ Manejo de errores comunes

Frontend

try {
const credential = await navigator.credentials.get({publicKey: options});
// Verificar con el servidor...
} catch (error) {
switch (error.name) {
case 'NotAllowedError':
console.log('Usuario canceló la autenticación');
break;
case 'TimeoutError':
console.log('Timeout de autenticación');
break;
case 'SecurityError':
console.log('Error de seguridad');
break;
}
}

Requisito previo: Debes haber obtenido opciones válidas de /auth/webauthn/authentication/options antes de intentar verificar una autenticación.