Autenticación
Authentication
Autenticación dual: JWT + api-key
Cada request a un endpoint protegido requiere dos credenciales simultáneas:
- JWT Bearer Token — valida la identidad del usuario (usuario/contraseña)
- api-key — UUID único del usuario API, enviado en un header separado
Ambas credenciales son obligatorias y deben pertenecer al mismo usuario. Un JWT de usuario A con api-key de usuario B es rechazado con
401.
Paso 1 — Obtener JWT
Las credenciales de acceso (usuario y contraseña) son entregadas por Prixmasol.
Envía usuario y contraseña para obtener los tokens de sesión:
POST /api/token/
Content-Type: application/json
{
"username": "tu_usuario",
"password": "tu_contraseña"
}
Response 200:
{
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
| Token | Vigencia | Uso |
|---|---|---|
access |
8 horas | Header Authorization: Bearer {token} en cada request |
refresh |
9 horas | Renovar el access token una vez sin re-autenticar |
El
refresh token permite un solo ciclo de renovación. Después de las 9 horas, debes hacer login nuevamente con POST /api/token/.
Paso 2 — Usar JWT en requests autenticados
Incluye ambos headers en cada llamada a endpoints protegidos:
POST /corresponsales/api/factura/consulta/
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
api-key: 550e8400-e29b-41d4-a716-446655440000
Content-Type: application/json
{
"invoice_id": "2025407608"
}
| Header | Descripción | Ejemplo |
|---|---|---|
Authorization |
JWT Bearer token (obligatorio) | Bearer eyJhbGc... |
api-key |
UUID del usuario API (obligatorio) | 550e8400-e29b-41d4-a716-446655440000 |
Content-Type |
Tipo de contenido | application/json |
Paso 3 — Renovar token expirado
Antes de que el access token expire (8h), puedes renovarlo con el refresh token:
POST /api/token/refresh/
Content-Type: application/json
{
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Response 200:
{
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Errores de autenticación
| HTTP | Mensaje | Causa |
|---|---|---|
401 |
Clave API no proporcionada | Falta el header api-key |
401 |
Clave API no corresponde al usuario autenticado | JWT y api-key pertenecen a usuarios distintos, o la api-key no existe |
401 |
(respuesta del framework JWT) | JWT ausente, malformado o expirado |
403 |
Usuario no autorizado para este endpoint | El usuario no tiene permiso en el endpoint solicitado |
Ejemplo completo en Python
import requests
BASE_URL = "https://TU-DOMINIO" # Reemplaza con la URL del ambiente
USERNAME = "tu_usuario"
PASSWORD = "tu_contraseña"
API_KEY = "550e8400-e29b-41d4-a716-446655440000" # UUID de tu API_User
# 1. Obtener JWT
resp = requests.post(f"{BASE_URL}/api/token/", json={
"username": USERNAME,
"password": PASSWORD,
})
resp.raise_for_status()
access_token = resp.json()["access"]
# 2. Consultar una factura
headers = {
"Authorization": f"Bearer {access_token}",
"api-key": API_KEY,
"Content-Type": "application/json",
}
resp = requests.post(
f"{BASE_URL}/corresponsales/api/factura/consulta/",
headers=headers,
json={"invoice_id": "2025407608"},
)
data = resp.json()
if data["status"] == "0" and data["data"].get("Usable"):
request_id = data["request_id"]
# 3. Notificar pago
resp = requests.post(
f"{BASE_URL}/corresponsales/api/factura/pago/",
headers=headers,
json={"request_id": request_id},
)
print(resp.json())
Buenas prácticas
- Nunca expongas tokens ni api-keys en logs o en el código fuente
- Renueva el
accesstoken antes de que expire (antes de las 8h) - El
refreshtoken dura 9h — solo vale para un ciclo de renovación, luego debes re-autenticarte - Usa HTTPS en todos los ambientes que no sean localhost
Dual authentication: JWT + api-key
Every request to a protected endpoint requires two simultaneous credentials:
- JWT Bearer Token — validates user identity (username/password)
- api-key — UUID unique to the API user, sent in a separate header
Both credentials are mandatory and must belong to the same user. A JWT from user A with api-key from user B is rejected with
401.
Step 1 — Get JWT
Access credentials (username and password) are provided by Prixmasol.
Send username and password to obtain session tokens:
POST /api/token/
Content-Type: application/json
{
"username": "your_username",
"password": "your_password"
}
Response 200:
{
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
| Token | Validity | Use |
|---|---|---|
access |
8 hours | Authorization: Bearer {token} header on each request |
refresh |
9 hours | Renew the access token once without re-authenticating |
The
refresh token allows one renewal cycle. After 9 hours you must log in again via POST /api/token/.
Step 2 — Use JWT in authenticated requests
Include both headers on every call to protected endpoints:
POST /corresponsales/api/factura/consulta/
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
api-key: 550e8400-e29b-41d4-a716-446655440000
Content-Type: application/json
{
"invoice_id": "2025407608"
}
| Header | Description | Example |
|---|---|---|
Authorization |
JWT Bearer token (required) | Bearer eyJhbGc... |
api-key |
API user UUID (required) | 550e8400-e29b-41d4-a716-446655440000 |
Content-Type |
Content type | application/json |
Step 3 — Renew expired token
Before the access token expires (8h), renew it using the refresh token:
POST /api/token/refresh/
Content-Type: application/json
{
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Response 200:
{
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Authentication errors
| HTTP | Message | Cause |
|---|---|---|
401 |
Clave API no proporcionada | Missing api-key header |
401 |
Clave API no corresponde al usuario autenticado | JWT and api-key belong to different users, or api-key not found |
401 |
(JWT framework response) | JWT missing, malformed, or expired |
403 |
Usuario no autorizado para este endpoint | User has no permission on the requested endpoint |
Complete Python example
import requests
BASE_URL = "https://YOUR-DOMAIN" # Replace with environment URL
USERNAME = "your_username"
PASSWORD = "your_password"
API_KEY = "550e8400-e29b-41d4-a716-446655440000" # Your API_User UUID
# 1. Get JWT
resp = requests.post(f"{BASE_URL}/api/token/", json={
"username": USERNAME,
"password": PASSWORD,
})
resp.raise_for_status()
access_token = resp.json()["access"]
# 2. Query an invoice
headers = {
"Authorization": f"Bearer {access_token}",
"api-key": API_KEY,
"Content-Type": "application/json",
}
resp = requests.post(
f"{BASE_URL}/corresponsales/api/factura/consulta/",
headers=headers,
json={"invoice_id": "2025407608"},
)
data = resp.json()
if data["status"] == "0" and data["data"].get("Usable"):
request_id = data["request_id"]
# 3. Notify payment
resp = requests.post(
f"{BASE_URL}/corresponsales/api/factura/pago/",
headers=headers,
json={"request_id": request_id},
)
print(resp.json())
Best practices
- Never expose tokens or api-keys in logs or source code
- Renew the
accesstoken before it expires (before the 8h mark) - The
refreshtoken lasts 9h and allows only one renewal cycle — re-authenticate after that - Use HTTPS in all environments other than localhost