Skip to main content

Login de Usuario

Endpoint principal para autenticar usuarios en el sistema SwapBits usando email y contraseña con verificación inteligente basada en dispositivos confiables y ubicación geográfica.


POST/auth/login

Autenticación principal que valida credenciales y determina el método de verificación requerido según el contexto de seguridad

📋 Parámetros

emailstringrequerido

Dirección de correo electrónico del usuario registrado

passwordstringrequerido

Contraseña del usuario

📤 Respuesta

{
"code": 1001,
"message": "Login successful",
"data": {
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "pinAuthToken": "uuid-v4-token"
}
}

Flujo de Autenticación

El sistema implementa un sistema inteligente de autenticación que evalúa múltiples factores de seguridad:

1. Validación de Credenciales

  • Verificación de formato de email
  • Validación de contraseña
  • Protección contra timing attacks con middleware de tiempo constante

2. Análisis de Contexto de Seguridad

El sistema evalúa:

  • Dirección IP del cliente
  • User-Agent del dispositivo
  • Ubicación geográfica (país y región)
  • Historial de dispositivos confiables
  • Estado de autenticación de dos factores (2FA)
  • Flag de bypass de seguridad del usuario

3. Determinación del Flujo de Verificación

Según el contexto, el sistema puede:

  • Login directo: Para dispositivos confiables sin 2FA
  • Verificación por email: Para nuevos dispositivos o ubicaciones
  • Verificación 2FA: Si el usuario tiene habilitado 2FA
  • Autorización de dispositivo: Para ubicaciones o IPs nuevas

Tipos de Respuesta

Respuestas Exitosas

Login Exitoso - Dispositivo Confiable

Código 1001 - Login exitoso en dispositivo previamente autorizado sin 2FA habilitado.

{
"code": 1001,
"message": "Login successful",
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"pinAuthToken": "550e8400-e29b-41d4-a716-446655440000"
}
}

Contextos que generan esta respuesta:

  • Usuario con bypassSecurity: true
  • Dispositivo confiable (IP + User-Agent previamente autorizados)
  • IP previamente confiable en sesión actual
  • Misma región que último login con IP confiable

Verificación por Código de Email

Código 1010 - Se requiere verificación por código enviado al email.

{
"code": 1010,
"message": "Verification code sent successfully",
"data": {
"verificationType": "EMAIL_CODE",
"token": "session-token-uuid"
}
}

Cuándo se genera:

  • Primer login del usuario sin 2FA
  • Nuevo dispositivo no confiable sin 2FA
  • Usuario no tiene 2FA habilitado

Verificación 2FA Requerida

Código 4014 - El usuario tiene 2FA habilitado, se requiere código TOTP.

{
"code": 4014,
"message": "Two-factor authentication is required",
"data": {
"verificationType": "2FA_CODE",
"token": "session-token-uuid"
}
}

Cuándo se genera:

  • Usuario tiene oauth2.twofa.enable: true
  • Incluso en dispositivos confiables si 2FA está activo

Errores de Autenticación

Credenciales Inválidas

Código 4007 - La contraseña proporcionada es incorrecta.

{
"code": 4007,
"message": "The provided password is incorrect",
"data": null
}

Usuario No Encontrado

Código 4001 - El email no está registrado en el sistema.

{
"code": 4001,
"message": "User not found",
"data": null
}

Datos Faltantes o Inválidos

Código 4006 - Faltan campos requeridos o formato de email inválido.

{
"code": 4006,
"message": "Missing required data",
"data": null
}

Errores de Seguridad

Nueva Ubicación Detectada

Código 4026 - Se detectó un intento de acceso desde una nueva ubicación geográfica.

{
"code": 4026,
"message": "New location detected. Please check your email to authorize access",
"data": null
}

Acción requerida:

  • El usuario recibirá un email con un enlace de autorización
  • Debe autorizar el nuevo dispositivo/ubicación antes de poder continuar
  • El enlace expira en 10 minutos

Dispositivo Previamente Revocado

Código 4025 - El dispositivo fue bloqueado manualmente por el usuario.

{
"code": 4025,
"message": "This device was previously revoked. Please check your email to authorize it again",
"data": null
}

Acción requerida:

  • Se envía email con enlace de desbloqueo
  • El usuario debe autorizar nuevamente el dispositivo

Ubicación No Autorizada

Código 4028 - Hay una verificación de ubicación pendiente que no se ha completado.

{
"code": 4028,
"message": "This location has not been authorized yet. Please check your email and authorize access first",
"data": null
}

Contexto:

  • Se generó una solicitud de autorización previa que aún no se completó
  • No se permiten nuevos intentos hasta autorizar o esperar a que expire (10 min)

Ejemplos de Implementación

JavaScript/TypeScript

Ejemplo con Fetch API
const loginUser = async (email, password) => {
try {
const response = await fetch('https://api.swapbits.co/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ email, password })
});

const result = await response.json();

switch (result.code) {
case 1001:
console.log('Login exitoso - dispositivo confiable');
// Guardar tokens y redirigir al dashboard
localStorage.setItem('accessToken', result.data.token);
localStorage.setItem('pinAuthToken', result.data.pinAuthToken);
window.location.href = '/dashboard';
break;

case 1010:
console.log('Código de verificación enviado por email');
// Redirigir a página de verificación de código
sessionStorage.setItem('sessionToken', result.data.token);
window.location.href = `/verify-email?token=${result.data.token}`;
break;

case 4014:
console.log('2FA requerido');
// Redirigir a verificación 2FA
sessionStorage.setItem('sessionToken', result.data.token);
window.location.href = `/verify-2fa?token=${result.data.token}`;
break;

case 4026:
console.log('Nueva ubicación detectada - revisar email');
alert('Se detectó una nueva ubicación. Revisa tu email para autorizar el acceso.');
break;

case 4007:
case 4001:
console.error('Credenciales inválidas');
alert('Email o contraseña incorrectos');
break;

default:
console.error('Error desconocido:', result.message);
}

return result;
} catch (error) {
console.error('Error en login:', error);
throw error;
}
};

// Uso
loginUser('usuario@ejemplo.com', 'MiPassword123!');

TypeScript con manejo de tipos

Login con tipos seguros
interface LoginResponse {
code: number;
message: string;
data: {
token?: string;
pinAuthToken?: string;
verificationType?: 'EMAIL_CODE' | '2FA_CODE';
} | null;
}

interface LoginCredentials {
email: string;
password: string;
}

const loginUser = async (
credentials: LoginCredentials
): Promise<LoginResponse> => {
const response = await fetch('https://api.swapbits.co/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(credentials),
});

if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Login failed');
}

return response.json();
};

// Uso con async/await
const handleLogin = async (email: string, password: string) => {
try {
const result = await loginUser({ email, password });

if (result.code === 1001 && result.data?.token) {
// Login exitoso directo
return {
success: true,
accessToken: result.data.token,
pinAuthToken: result.data.pinAuthToken,
requiresVerification: false
};
} else if (result.code === 1010 || result.code === 4014) {
// Requiere verificación
return {
success: true,
sessionToken: result.data?.token,
verificationType: result.data?.verificationType,
requiresVerification: true
};
}

return { success: false, error: result.message };
} catch (error) {
console.error('Login error:', error);
return { success: false, error: error.message };
}
};

Python

Ejemplo con requests
import requests
from typing import Dict, Optional

def login_user(email: str, password: str) -> Dict:
"""
Realizar login de usuario con manejo completo de respuestas

Args:
email: Email del usuario
password: Contraseña del usuario

Returns:
Diccionario con el resultado del login
"""
url = 'https://api.swapbits.co/auth/login'
data = {'email': email, 'password': password}

try:
response = requests.post(url, json=data, timeout=10)
result = response.json()

if result['code'] == 1001:
# Login exitoso directo
print("Login exitoso - dispositivo confiable")
return {
'success': True,
'access_token': result['data']['token'],
'pin_auth_token': result['data']['pinAuthToken'],
'requires_verification': False
}

elif result['code'] == 1010:
# Código de email requerido
print("Código de verificación enviado por email")
return {
'success': True,
'session_token': result['data']['token'],
'verification_type': 'EMAIL_CODE',
'requires_verification': True
}

elif result['code'] == 4014:
# 2FA requerido
print("Autenticación 2FA requerida")
return {
'success': True,
'session_token': result['data']['token'],
'verification_type': '2FA_CODE',
'requires_verification': True
}

elif result['code'] == 4026:
# Nueva ubicación
print("Nueva ubicación detectada - revisar email")
return {
'success': False,
'error': result['message'],
'action_required': 'check_email'
}

elif result['code'] in [4001, 4007]:
# Credenciales inválidas
print(f"Error: {result['message']}")
return {
'success': False,
'error': result['message']
}

else:
print(f"Error desconocido: {result['message']}")
return {
'success': False,
'error': result['message']
}

except requests.exceptions.RequestException as e:
print(f"Error de conexión: {e}")
return {
'success': False,
'error': str(e)
}

# Ejemplo de uso
if __name__ == '__main__':
result = login_user('usuario@ejemplo.com', 'MiPassword123!')

if result['success']:
if not result.get('requires_verification'):
print(f"Access Token: {result['access_token']}")
else:
print(f"Verificación requerida: {result['verification_type']}")
else:
print(f"Login fallido: {result['error']}")

cURL

Comando cURL básico
curl -X POST 'https://api.swapbits.co/auth/login' \
-H 'Content-Type: application/json' \
-d '{
"email": "usuario@ejemplo.com",
"password": "MiPassword123!"
}'
cURL con procesamiento de respuesta
#!/bin/bash

EMAIL="usuario@ejemplo.com"
PASSWORD="MiPassword123!"

response=$(curl -s -X POST 'https://api.swapbits.co/auth/login' \
-H 'Content-Type: application/json' \
-d "{
\"email\": \"$EMAIL\",
\"password\": \"$PASSWORD\"
}")

code=$(echo $response | jq -r '.code')
message=$(echo $response | jq -r '.message')

case $code in
1001)
echo "Login exitoso"
token=$(echo $response | jq -r '.data.token')
echo "Access Token: $token"
;;
1010)
echo "Verificación por email requerida"
;;
4014)
echo "2FA requerido"
;;
*)
echo "Error: $message"
;;
esac

Sistema de Dispositivos Confiables

El sistema mantiene un registro de dispositivos confiables basado en:

Criterios de Confianza

Factores de Identificación

  1. IP Address: Dirección IP del cliente
  2. User-Agent: Identificador del navegador/dispositivo
  3. Región Geográfica: País y región del acceso
  4. Historial de Sesiones: Sesiones previamente autorizadas

Flujos de Autorización

Dispositivo Confiable

  • Login directo sin código de email
  • Solo requiere 2FA si está habilitado
  • Se emite token JWT inmediatamente

Dispositivo Nuevo - Misma Región

  • Se envía email de autorización
  • Usuario debe aprobar el nuevo dispositivo
  • Después de aprobación, se convierte en confiable

Dispositivo Nuevo - Nueva Región

  • Se envía email de autorización
  • Validación adicional de seguridad
  • Registro de actividad de ubicación sospechosa

Sistema de Seguridad Avanzado

Bypass de Seguridad

Bypass de Seguridad

Los usuarios con flag bypassSecurity: true obtienen acceso directo sin verificaciones adicionales. Útil para:

  • Cuentas de servicio
  • Testing
  • Usuarios de confianza absoluta

Registro de Actividad

Cada intento de login se registra con:

  • Información geográfica completa
  • Detalles del dispositivo (OS, navegador, tipo)
  • Huella digital del dispositivo
  • Tipo de resultado (exitoso, fallido, bloqueado)
  • Metadata adicional de seguridad

Limpieza Automática

El sistema limpia automáticamente:

  • Sesiones expiradas antes de crear nuevas
  • Sesiones pendientes de autorización caducadas
  • Intentos de verificación antiguos

Validaciones y Restricciones

Formato de Email

  • Debe cumplir con regex: /^[^\s@]+@[^\s@]+\.[^\s@]+$/
  • No se permiten espacios
  • Debe contener @ y dominio válido

Formato de Contraseña

  • Mínimo 9 caracteres
  • Al menos una letra minúscula
  • Al menos una letra mayúscula
  • Al menos un dígito
  • Al menos un carácter especial

Rate Limiting

  • Protección contra intentos de bypass de verificación
  • Bloqueo temporal por múltiples intentos fallidos
  • Registro de intentos sospechosos

Próximos Pasos

Después del Login

Dependiendo de la respuesta del endpoint /auth/login:

Si código 1001 (Login exitoso directo):

  1. Guardar token como JWT de acceso
  2. Guardar pinAuthToken para verificaciones PIN de sesión
  3. Redirigir al dashboard o página principal

Si código 1010 (Verificación por email):

  1. Guardar token de sesión temporal
  2. Redirigir a Verificar Código de Email
  3. Ingresar código de 6 dígitos recibido por email

Si código 4014 (Verificación 2FA):

  1. Guardar token de sesión temporal
  2. Redirigir a Verificar Código 2FA
  3. Ingresar código TOTP de aplicación autenticadora

Si código 4026 (Nueva ubicación):

  1. Informar al usuario que revise su email
  2. Esperar autorización de dispositivo
  3. Reintentar login después de autorizar

Si código 4025 (Dispositivo bloqueado):

  1. Informar al usuario que revise su email
  2. Seguir enlace de desbloqueo
  3. Reintentar login después de desbloquear

Probar esta API

API Explorer

Visita el API Explorer - Login para hacer pruebas interactivas con este endpoint en tiempo real.

En el API Explorer podrás:

  • Enviar peticiones reales a la API
  • Ver respuestas en tiempo real
  • Probar diferentes escenarios de autenticación
  • Experimentar con dispositivos confiables y nuevos
  • Simular diferentes ubicaciones geográficas

Enlaces Relacionados