Cuando construyes una API, garantizar que solo usuarios autorizados accedan a ciertos recursos es fundamental. FastAPI ofrece mecanismos sencillos y potentes para implementar autenticación directamente en tus endpoints, y el más rápido de todos es la protección con usuario y contraseña mediante HttpBasicCredentials.
¿Cómo funciona la autenticación básica en FastAPI?
FastAPI permite agregar seguridad a un endpoint específico usando el esquema de autenticación HTTP Basic. Este esquema muestra un cuadro de login donde el usuario debe ingresar su nombre de usuario y contraseña antes de poder consumir el recurso.
El flujo es simple:
- Se define una instancia de HttpBasic como mecanismo de seguridad.
- Se agrega una dependencia al endpoint que recibe las credenciales.
- FastAPI detecta automáticamente el tipo de la variable y ejecuta la lógica de autenticación.
Antes de aplicar cualquier protección, al abrir la documentación automática de FastAPI todos los endpoints están accesibles sin restricción: basta con pulsar Try out y ejecutar [0:38].
¿Cómo se implementa HttpBasicCredentials paso a paso?
Para agregar autenticación al endpoint root, se necesitan varias importaciones y ajustes en el código.
¿Qué dependencias e importaciones se requieren?
Primero se importa HTTPBasic y HTTPBasicCredentials desde fastapi.security, junto con Depends y Annotated [1:30]. El patrón completo luce así:
python
from typing import Annotated
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials
security = HTTPBasic()
Luego, en la función del endpoint, se agrega el parámetro credentials usando Annotated para que FastAPI lo reconozca como una dependencia y no como un valor ingresado por el usuario:
python
@app.get("/")
def root(credentials: Annotated[HTTPBasicCredentials, Depends(security)]):
return {"message": f"Hola, {credentials.username}"}
El uso de Annotated resuelve errores de tipado y habilita el autocompletado en el editor, facilitando el acceso a credentials.username y credentials.password dentro del método [2:05].
¿Qué cambia en la documentación interactiva?
Al recargar la documentación de FastAPI aparece un nuevo botón de Authorize [2:30]. Al hacer clic, se despliega un formulario que solicita usuario y contraseña. Además, el endpoint protegido muestra un ícono de candado abierto, que indica que requiere autenticación.
Cada vez que un usuario se autentica, la variable credentials se llena con los valores proporcionados. Esto se puede verificar imprimiendo las credenciales en consola y ejecutando el endpoint desde distintas ventanas del navegador [3:00].
¿Cómo validar credenciales y retornar errores adecuados?
Con las credenciales disponibles, el siguiente paso es validar si el usuario y la contraseña son correctos. En un escenario real, esta validación se haría contra una base de datos; en el ejemplo se simula con valores fijos:
python
@app.get("/")
def root(credentials: Annotated[HTTPBasicCredentials, Depends(security)]):
if credentials.username == "LC Martínez" and credentials.password == "QWERTY":
return {"message": f"Hola, {credentials.username}"}
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="No está autorizado para acceder a este endpoint"
)
El código de estado 401 Unauthorized es el estándar HTTP para indicar que las credenciales proporcionadas no son válidas [4:10]. Se lanza mediante HTTPException, la clase de FastAPI diseñada para retornar respuestas de error con un status code y un mensaje descriptivo.
Al probar con datos incorrectos, la API responde con el mensaje de error. Al ingresar las credenciales correctas, retorna el saludo personalizado [4:45].
Como reto, aplica esta misma autenticación a los demás endpoints que consideres sensibles. Además, asegúrate de que la contraseña no quede visible en el código fuente: puedes usar variables de entorno o archivos de configuración para mantenerla segura. ¿Qué estrategia usarías para proteger esas credenciales? Comparte tu solución en los comentarios.