Saltar al contenido principal

Verificar autenticación WebAuthn

Verifica la respuesta devuelta por navigator.credentials.get() y, si es válida, entrega un token JWT para acceso autenticado.


✅ Paso final del Login con WebAuthn

Este endpoint valida el challenge, la firma y el origen de la autenticación. Si todo es correcto, devuelve accessToken (JWT) y metadata de la credencial utilizada.

POST/auth/webauthn/authentication/verify

Verifica autenticación WebAuthn y emite JWT si es válida

📋 Parámetros

emailstringrequerido

Correo electrónico del usuario que se autentica

credentialobjectrequerido

Objeto credencial generado por navigator.credentials.get()

📤 Respuesta

{
"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"
}
}

Contexto de Uso

Este endpoint se usa después de obtener opciones y solicitar la autenticación en el navegador:

  1. Obtener opciones desde /auth/webauthn/authentication/options (o el endpoint público equivalente si aplica)
  2. Ejecutar navigator.credentials.get({ publicKey: options })
  3. Enviar el resultado a este endpoint para verificación y emisión de JWT

Request Body

{
"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"
}
}

Tipos de Respuesta

Respuesta Exitosa

Autenticación exitosa (200)

Si la autenticación es válida, el servidor devuelve verified=true y un accessToken (JWT).

{
"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"
}
}

Errores

Credencial inválida / challenge inválido (400)

Ejemplos de errores comunes de validación:

Credencial inválida (firma):

{
"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: coincide con el generado para esta autenticación
  2. Firma: verificación criptográfica con la clave pública almacenada
  3. Contador: control de incremento para detectar clonación
  4. Origen: dominio correcto (RP ID / origin)
  5. Usuario: la credencial pertenece al usuario especificado

Datos actualizados

  • Último uso de la credencial
  • Contador incrementado
  • Logs de auditoría del intento y resultado

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
})
});

const result = await verifyResponse.json();

if (result.verified) {
localStorage.setItem('token', result.accessToken);
// Redirigir a área autenticada
}

Información del Token JWT

Contenido típico del JWT

El token generado incluye (según configuración):

  • ID de usuario (sub / userId)
  • Roles y permisos
  • Expiración (ttl)
  • Metadata del método de autenticación (WebAuthn)

Manejo de Errores Comunes (Cliente)

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;
}
}

Notas

Notas

  • La credencial debe obtenerse usando opciones de /auth/webauthn/authentication/options
  • Una autenticación exitosa provee acceso equivalente a un login tradicional
  • Se actualiza automáticamente la fecha de último uso y el contador
  • Compatible con flujos existentes (2FA, verificaciones adicionales, etc.)

Endpoints Relacionados