Visión General

La autenticación en las APIs de Imagina Energía se basa en el estándar JSON Web Token (JWT). Cada solicitud a endpoints protegidos debe incluir un token JWT válido en el encabezado de autorización.

📌 Importante Para utilizar las APIs necesitas:
  • Un token JWT válido (obtenido mediante autenticación)
  • Permisos configurados en tu cuenta de usuario
  • Conocer el ambiente correcto (PRE o Producción)

Obtener un Token JWT

Para obtener tu token JWT, debes autenticarte con tus credenciales en el endpoint de autenticación.

Endpoint de Autenticación

POST https://oezimzeqmtmncuipqgwd.supabase.co/functions/v1/initiateauthcommand
⚠️ Entorno PRE La URL mostrada corresponde al entorno de PRE-PRODUCCIÓN. Contacta con el administrador para obtener la URL de producción.

Solicitud de Login

Envía tus credenciales en formato JSON:

cURL
curl -X POST https://oezimzeqmtmncuipqgwd.supabase.co/functions/v1/initiateauthcommand \
  -H "Content-Type: application/json" \
  -d '{
    "email": "tu_usuario@ejemplo.com",
    "password": "tu_contraseña"
  }'

Respuesta Exitosa

Si las credenciales son correctas, recibirás:

JSON
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires_in": 3600
}
✅ Token Obtenido Guarda este token de forma segura. Lo necesitarás para todas tus solicitudes posteriores. El campo expires_in indica la validez del token en segundos (normalmente 1 hora).

Usar el Token en tus Peticiones

Una vez obtenido el token, debes incluirlo en el encabezado Authorization de todas las solicitudes a endpoints protegidos.

Formato del Encabezado

Authorization: Bearer <tu_token_jwt>

Ejemplo de Solicitud

Consultando un contrato:

cURL
curl -X GET "https://pre-webhooks.imaginaenergia.com/contrato?contrato_id=12345" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Validez del Token

⏰ Duración del Token:

  • Los tokens tienen un tiempo de expiración limitado (normalmente 1 hora)
  • Cuando un token expira, recibirás un error 401 Unauthorized
  • Deberás autenticarte nuevamente para obtener un token fresco

Impersonación de Canal

La impersonación de canal te permite realizar operaciones en nombre de un canal específico, en lugar de usar tu canal por defecto. Esto es útil cuando gestionas múltiples canales o necesitas realizar operaciones administrativas.

Requisitos para Impersonar

Para poder impersonar un canal necesitas:

  1. El permiso impersonar_canal asignado a tu usuario
  2. Un ID de permiso específico (UUID) proporcionado por el administrador
⚠️ Importante El valor de X-Canal debe ser el ID del permiso (UUID), NO el ID del canal directamente. Este UUID te lo proporciona el administrador del sistema.

Cómo Impersonar un Canal

Incluye el encabezado X-Canal con el ID de permiso en tu solicitud:

cURL
curl -X GET "https://pre-webhooks.imaginaenergia.com/contrato?contrato_id=12345" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "X-Canal: 550e8400-e29b-41d4-a716-446655440000"

Comportamiento de la Impersonación

Escenario Comportamiento
Sin encabezado X-Canal Las operaciones se realizan con tu canal por defecto
Con X-Canal válido Las operaciones se realizan en nombre del canal impersonado
Con X-Canal sin permisos Recibirás un error 401 Unauthorized

Ejemplo Completo con Python

Python
import requests

# Configuración
api_url = "https://pre-webhooks.imaginaenergia.com/contrato"
jwt_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
permiso_id = "550e8400-e29b-41d4-a716-446655440000"

# Headers con impersonación
headers = {
    "Authorization": f"Bearer {jwt_token}",
    "X-Canal": permiso_id
}

# Realizar solicitud
params = {"contrato_id": "12345"}
response = requests.get(api_url, headers=headers, params=params)

if response.status_code == 200:
    print("✅ Solicitud exitosa:", response.json())
else:
    print(f"❌ Error {response.status_code}:", response.json())

Códigos de Error de Autenticación

El sistema puede devolver los siguientes errores relacionados con autenticación:

Código Descripción Solución
401 Token JWT inválido o expirado Obtén un nuevo token autenticándote
401 Token no proporcionado Incluye el encabezado Authorization
401 Error en impersonación de canal Verifica el ID de permiso y tus permisos
403 No tienes permisos para esta operación Contacta con el administrador

Ejemplo de Respuesta de Error

JSON
{
  "error": "Authentication failed",
  "message": "Invalid or expired token"
}

Mejores Prácticas de Seguridad

Gestión del Token

1 Nunca compartas tu token JWT con otras personas

2 No incluyas el token en URLs o logs públicos

3 Almacena el token de forma segura en variables de entorno o sistemas de gestión de secretos

4 Renueva el token periódicamente antes de que expire

Uso de Impersonación

  • Solicita al administrador solo los permisos de impersonación que realmente necesites
  • Documenta internamente qué operaciones realizas con cada canal impersonado
  • Verifica que estás usando el ID de permiso correcto antes de realizar operaciones críticas

Ejemplos de Código Completos

Python con Requests

Python
import requests
import os

# 1. Obtener token JWT
def get_jwt_token(email, password):
    url = "https://oezimzeqmtmncuipqgwd.supabase.co/functions/v1/initiateauthcommand"
    payload = {
        "email": email,
        "password": password
    }
    
    response = requests.post(url, json=payload)
    
    if response.status_code == 200:
        data = response.json()
        return data["token"]
    else:
        raise Exception(f"Error de autenticación: {response.text}")

# 2. Realizar petición autenticada
def get_contrato(token, contrato_id, permiso_canal=None):
    url = "https://pre-webhooks.imaginaenergia.com/contrato"
    
    headers = {
        "Authorization": f"Bearer {token}"
    }
    
    # Agregar impersonación si se proporciona
    if permiso_canal:
        headers["X-Canal"] = permiso_canal
    
    params = {"contrato_id": contrato_id}
    
    response = requests.get(url, headers=headers, params=params)
    
    if response.status_code == 200:
        return response.json()
    elif response.status_code == 401:
        raise Exception("Token inválido o expirado")
    else:
        raise Exception(f"Error {response.status_code}: {response.text}")

# Uso
try:
    # Autenticarse
    token = get_jwt_token(
        email=os.getenv("API_EMAIL"),
        password=os.getenv("API_PASSWORD")
    )
    print("✅ Token obtenido")
    
    # Consultar contrato
    contrato = get_contrato(
        token=token,
        contrato_id="12345",
        permiso_canal="550e8400-e29b-41d4-a716-446655440000"  # Opcional
    )
    print("✅ Contrato:", contrato)
    
except Exception as e:
    print(f"❌ Error: {e}")

JavaScript con Fetch

JavaScript
// 1. Obtener token JWT
async function getJwtToken(email, password) {
    const url = 'https://oezimzeqmtmncuipqgwd.supabase.co/functions/v1/initiateauthcommand';
    
    const response = await fetch(url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({ email, password })
    });
    
    if (!response.ok) {
        throw new Error(`Error de autenticación: ${response.statusText}`);
    }
    
    const data = await response.json();
    return data.token;
}

// 2. Realizar petición autenticada
async function getContrato(token, contratoId, permisoCanal = null) {
    const url = `https://pre-webhooks.imaginaenergia.com/contrato?contrato_id=${contratoId}`;
    
    const headers = {
        'Authorization': `Bearer ${token}`
    };
    
    // Agregar impersonación si se proporciona
    if (permisoCanal) {
        headers['X-Canal'] = permisoCanal;
    }
    
    const response = await fetch(url, { headers });
    
    if (!response.ok) {
        throw new Error(`Error ${response.status}: ${response.statusText}`);
    }
    
    return await response.json();
}

// Uso
(async () => {
    try {
        // Autenticarse
        const token = await getJwtToken(
            'tu_usuario@ejemplo.com',
            'tu_contraseña'
        );
        console.log('✅ Token obtenido');
        
        // Consultar contrato
        const contrato = await getContrato(
            token,
            '12345',
            '550e8400-e29b-41d4-a716-446655440000' // Opcional
        );
        console.log('✅ Contrato:', contrato);
        
    } catch (error) {
        console.error('❌ Error:', error.message);
    }
})();

Gestión de Errores Completa

Python
import requests
from typing import Optional, Dict, Any

class ImaginaEnergiaAPI:
    def __init__(self, email: str, password: str):
        self.email = email
        self.password = password
        self.token: Optional[str] = None
        self.base_url = "https://pre-webhooks.imaginaenergia.com"
        
    def authenticate(self) -> bool:
        """Obtiene un nuevo token JWT"""
        url = "https://oezimzeqmtmncuipqgwd.supabase.co/functions/v1/initiateauthcommand"
        
        try:
            response = requests.post(url, json={
                "email": self.email,
                "password": self.password
            })
            
            if response.status_code == 200:
                data = response.json()
                self.token = data["token"]
                print(f"✅ Autenticado. Token expira en {data['expires_in']} segundos")
                return True
            elif response.status_code == 401:
                print("❌ Credenciales inválidas")
                return False
            else:
                print(f"❌ Error de autenticación: {response.text}")
                return False
                
        except Exception as e:
            print(f"❌ Error de conexión: {e}")
            return False
    
    def _make_request(self, method: str, endpoint: str, 
                     permiso_canal: Optional[str] = None,
                     **kwargs) -> Dict[Any, Any]:
        """Realiza una petición HTTP con manejo de errores"""
        
        if not self.token:
            raise Exception("No hay token. Llama a authenticate() primero")
        
        headers = {
            "Authorization": f"Bearer {self.token}"
        }
        
        if permiso_canal:
            headers["X-Canal"] = permiso_canal
        
        url = f"{self.base_url}{endpoint}"
        
        try:
            response = requests.request(method, url, headers=headers, **kwargs)
            
            if response.status_code == 200:
                return response.json()
            elif response.status_code == 401:
                # Token expirado, intentar re-autenticar
                print("⚠️  Token expirado, re-autenticando...")
                if self.authenticate():
                    # Reintentar con nuevo token
                    headers["Authorization"] = f"Bearer {self.token}"
                    response = requests.request(method, url, headers=headers, **kwargs)
                    return response.json()
                else:
                    raise Exception("No se pudo re-autenticar")
            elif response.status_code == 403:
                raise Exception("Acceso prohibido: no tienes permisos")
            elif response.status_code == 404:
                raise Exception("Recurso no encontrado")
            else:
                raise Exception(f"Error {response.status_code}: {response.text}")
                
        except requests.RequestException as e:
            raise Exception(f"Error de conexión: {e}")
    
    def get_contrato(self, contrato_id: str, 
                    permiso_canal: Optional[str] = None) -> Dict[Any, Any]:
        """Consulta un contrato específico"""
        return self._make_request(
            "GET",
            "/contrato",
            permiso_canal=permiso_canal,
            params={"contrato_id": contrato_id}
        )

# Uso
api = ImaginaEnergiaAPI("tu_usuario@ejemplo.com", "tu_contraseña")

if api.authenticate():
    try:
        contrato = api.get_contrato("12345")
        print(f"✅ Contrato obtenido: {contrato}")
    except Exception as e:
        print(f"❌ Error: {e}")
💬 ¿Necesitas Ayuda? Para problemas técnicos, dudas o solicitudes de acceso, contacta con: serviciosistemas@imaginaenergia.com