1. Crear la función en AWS Lambda
Paso 1: Acceder a la consola de Lambda
- Inicia sesión en tu Consola de AWS.
- En el buscador, escribe “Lambda” y selecciona AWS Lambda.
- Haz clic en Create function (Crear función).
Paso 2: Configurar la función
- Selecciona “Author from scratch” (Autor desde cero).
- Completa los campos:
- Function name:
assign_badges_lambda
- Runtime:
Python 3.11
- Architecture:
x86_64
- Execution role:
- Selecciona “Create a new role with basic Lambda permissions”.
- Function name:
- Haz clic en Create function.
2. Crear el código y sus dependencias
Necesitamos un deployment package (archivo ZIP) con nuestro código en lambda_function.py
y las librerías (por ejemplo, requests
).
Paso 1: Preparar el paquete localmente
- Crea una carpeta, por ejemplo:
su-lambda
. - Dentro de
su-lambda
, crealambda_function.py
con un ejemplo de código que usa un refresh token si el access token está expirado. Asumamos que en tu API hay un endpoint/auth/login/refresh/
que recibe{"refresh": "<REFRESH_TOKEN>"}
y retorna un nuevo access token
import requests
import os
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def refresh_access_token(session, refresh_url, refresh_token):
"""
Solicita un nuevo access token usando el refresh token.
Retorna el nuevo token o None si falla.
"""
logger.info("Attempting to refresh access token...")
try:
# Suponemos que tu API de refresh es un POST a refresh_url con el JSON: {"refresh": "<REFRESH_TOKEN>"}
response = session.post(refresh_url, json={"refresh": refresh_token})
response.raise_for_status()
data = response.json()
new_access = data.get("access")
if new_access:
logger.info("Access token refreshed successfully.")
return new_access
else:
logger.error("Refresh response did not include an 'access' token.")
return None
except requests.exceptions.RequestException as e:
logger.error(f"Error refreshing token: {str(e)}")
return None
def lambda_handler(event, context):
logger.info("Lambda function started execution.")
# Leer variables de entorno
API_URL = os.environ.get("DJANGO_API_URL", "https://api.ejemplo.com/assign-badges/")
REFRESH_URL = os.environ.get("DJANGO_REFRESH_URL", "https://api.ejemplo.com/auth/login/refresh/")
ACCESS_TOKEN = os.environ.get("DJANGO_API_ACCESS_TOKEN") # Access Token inicial
REFRESH_TOKEN = os.environ.get("DJANGO_API_REFRESH_TOKEN") # Refresh Token
if not ACCESS_TOKEN or not REFRESH_TOKEN:
logger.error("Access or Refresh token is missing. Check environment variables.")
return {
'statusCode': 500,
'body': 'Missing tokens in environment variables'
}
# Usar requests.Session() para manejar cookies si fuera necesario.
session = requests.Session()
headers = {
'Authorization': f'Bearer {ACCESS_TOKEN}',
'Content-Type': 'application/json'
}
try:
# Intentar la llamada principal
logger.info(f"Sending request to {API_URL}")
response = session.post(API_URL, headers=headers)
# Si el access token está expirado, la API podría responder 401
if response.status_code == 401:
logger.info("Access token expired. Attempting to refresh...")
new_access = refresh_access_token(session, REFRESH_URL, REFRESH_TOKEN)
if new_access:
# Actualiza el header con el nuevo token
headers['Authorization'] = f'Bearer {new_access}'
# Reintenta la solicitud
logger.info("Retrying the API call with new access token...")
response = session.post(API_URL, headers=headers)
else:
logger.error("Could not refresh access token. Aborting.")
return {
'statusCode': 401,
'body': 'Unable to refresh token'
}
# Manejo final de la respuesta
response.raise_for_status()
logger.info(f"Response Status: {response.status_code}")
logger.info(f"Response Content: {response.text}")
return {
'statusCode': 200,
'body': 'Badges assigned successfully!'
}
except requests.exceptions.RequestException as e:
logger.error(f"Error calling the API: {str(e)}")
return {
'statusCode': 500,
'body': f'Error: {str(e)}'
}
- Comprime todo en un ZIP:bashCopy
zip -r deployment_package.zip .
Notas:
refresh_access_token
realiza el flujo para solicitar un nuevo access token.- Se asume que la API regresa JSON con una clave
"access"
si todo va bien. - Si tu API maneja cookies/CSRF, deberás ampliar el código para obtener un
csrftoken
y adjuntarlo en cada llamada.
3.- Desde la carpeta su-lambda
, instala las dependencias (p.ej. requests
):
pip3 install requests -t .
4.- Comprime todo en un ZIP:
zip -r deployment_package.zip .
Paso 2: Subir el ZIP a AWS Lambda
- Vuelve a la consola de AWS Lambda, selecciona tu función
assign_badges_lambda
. - Ve a la pestaña Code y haz clic en “Upload from” → “.zip file”.
- Selecciona
deployment_package.zip
y confirma. - Haz clic en Deploy.
3. Configurar las variables de entorno
Ve a la pestaña Configuration → Environment variables para especificar la URL de tu API, el access token, el refresh token, etc.
Por ejemplo:
- Key:
DJANGO_API_URL
Value:https://api.ejemplo.com/assign-badges/
- Key:
DJANGO_REFRESH_URL
Value:https://api.ejemplo.com/auth/login/refresh/
- Key:
DJANGO_API_ACCESS_TOKEN
Value:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
(token inicial) - Key:
DJANGO_API_REFRESH_TOKEN
Value:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
(refresh token)
Consejo:
Si manejas credenciales reales (usuario/contraseña, tokens, etc.), es más seguro usar AWS Secrets Manager o AWS Systems Manager Parameter Store con cifrado y rotación.
4. Programar la ejecución con AWS EventBridge
Para que tu Lambda se ejecute automáticamente (por ejemplo, a diario):
- Ve a EventBridge en la consola de AWS.
- Haz clic en Rules → Create rule.
- Asigna un nombre, por ejemplo
DailyAssignBadges
. - Selecciona Schedule y usa una cron expression. Por ejemplo, para medianoche diaria:scssCopy
cron(0 0 * * ? *)
- En Select target, elige Lambda function y selecciona
assign_badges_lambda
. - Haz clic en Create.
5. Monitoreo con CloudWatch
- En la consola de AWS, abre CloudWatch.
- Selecciona Logs → Log groups.
- Busca
/aws/lambda/assign_badges_lambda
. - Haz clic para ver los registros, donde encontrarás info y errores (
logger.info
,logger.error
).
6. Pruebas y Verificación
- En Lambda, ve a la pestaña Test.
- Crea un evento de prueba (un JSON sencillo, por ejemplo:
{"test": "run"}
). - Ejecuta la prueba y verifica si la invocación es
SUCCESS
oERROR
. - Abre CloudWatch para ver los logs y diagnosticar cualquier problema.
Notas sobre Cookies y CSRF
- Si tu API utiliza cookies para manejar la sesión y requiere un
csrftoken
, necesitarás:- Hacer un
GET
inicial para obtener la cookie. - Leer la cookie
csrftoken
y enviarla en la cabeceraX-CSRFToken
. - Incluir la cookie en cada
POST
(consession.cookies
o la cabeceraCookie: ...
).
- Hacer un
- Si tu API no exenta los endpoints de JWT del CSRF, ajusta la configuración de Django o DRF (
@csrf_exempt
en las vistas o configuraciones avanzadas) para que no bloquee las peticiones “headless” con tokens.
Conclusión
Con este flujo:
- Desplegaste una función Lambda con
requests
. - Manejaste un refresh token para reobtener un access token cuando sea necesario.
- Configuraste variables de entorno (o Secrets Manager) para no exponer credenciales en el código.
- Programaste la ejecución con EventBridge y monitoreas logs en CloudWatch.
Así, tu Lambda podrá comunicarse con APIs seguras (JWT + refresh tokens) sin necesidad de reingresar manualmente credenciales, y ejecutar la lógica de asignar medallas (u otra tarea) de forma automática.