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
- Challenge: Verifica que el challenge coincida con el generado para autenticación
- Firma: Valida la firma criptográfica usando la clave pública almacenada
- Contador: Verifica el contador de uso para detectar credenciales clonadas
- Origen: Confirma que la autenticación fue realizada para el dominio correcto
- 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
/auth/webauthn/authentication/options- Obtener opciones de autenticación/auth/webauthn/credentials(endpoint documentation) - Gestionar credenciales del usuario/auth/login- Método de autenticación tradicional alternativo
⚡ 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/optionsantes de intentar verificar una autenticación.