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.
/auth/loginAutenticación principal que valida credenciales y determina el método de verificación requerido según el contexto de seguridad
📋 Parámetros
emailstringrequeridoDirección de correo electrónico del usuario registrado
passwordstringrequeridoContraseñ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
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
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
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
curl -X POST 'https://api.swapbits.co/auth/login' \
-H 'Content-Type: application/json' \
-d '{
"email": "usuario@ejemplo.com",
"password": "MiPassword123!"
}'
#!/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
- IP Address: Dirección IP del cliente
- User-Agent: Identificador del navegador/dispositivo
- Región Geográfica: País y región del acceso
- 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):
- Guardar
tokencomo JWT de acceso - Guardar
pinAuthTokenpara verificaciones PIN de sesión - Redirigir al dashboard o página principal
Si código 1010 (Verificación por email):
- Guardar
tokende sesión temporal - Redirigir a Verificar Código de Email
- Ingresar código de 6 dígitos recibido por email
Si código 4014 (Verificación 2FA):
- Guardar
tokende sesión temporal - Redirigir a Verificar Código 2FA
- Ingresar código TOTP de aplicación autenticadora
Si código 4026 (Nueva ubicación):
- Informar al usuario que revise su email
- Esperar autorización de dispositivo
- Reintentar login después de autorizar
Si código 4025 (Dispositivo bloqueado):
- Informar al usuario que revise su email
- Seguir enlace de desbloqueo
- 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