Skip to content

Capítulo 6.5: Fundamentos de la seguridad de API

Tiempo de estudio: 45 minutos


1. Seguridad API: Defensa multinivel de la estación

Imagine que su estación espacial (API) se encuentra en un sector hostil del espacio. Un solo campo de fuerza (autenticación) no es suficiente. Necesita un sistema de defensa integral:

  • Escudos (HTTPS): Cifrado de todo el tráfico.
  • Sensores de anomalías (Rate Limiting): Protección contra solicitudes demasiado frecuentes.
  • Mamparos internos (Autorización): Separación de derechos de acceso.
  • Inspección de cargas (Validación): No confiar en ningún dato entrante.
  • Caja fuerte secreta (Variables de entorno): Almacenamiento seguro de claves.

Configuremos cada uno de estos niveles.


2. Escudos: Siempre use HTTPS

¿Qué es esto? HTTPS (HyperText Transfer Protocol Secure) es una versión del protocolo HTTP que cifra todos los datos entre el cliente y el servidor. Sin él, cualquiera que esté "escuchando" la red (por ejemplo, en una red Wi-Fi pública) puede interceptar inicios de sesión, contraseñas y tokens.

¿Cómo implementarlo?

  • En producción — obligatorio. Al desplegar su API en un servidor real (Heroku, DigitalOcean, etc.), configure el servidor web (Nginx, Apache) para trabajar con un certificado SSL. Servicios como Let's Encrypt proporcionan certificados gratuitos.
  • En el desarrollo local, es menos crítico, pero herramientas como Laravel Herd o mkcert permiten configurar fácilmente HTTPS local.

💡 Regla n.º 1 en seguridad de API: No hay HTTPS, no hay seguridad.


3. Sensores de anomalías: Limitación de la tasa de solicitudes (Rate Limiting)

¿Qué es esto? Protección contra ataques de fuerza bruta (cuando un atacante intenta adivinar una contraseña enviando miles de solicitudes por segundo) y contra ataques DoS (cuando el servidor es "bombardeado" con solicitudes para que deje de responder). Rate Limiting limita el número de solicitudes que un usuario (o dirección IP) puede realizar en un período de tiempo determinado.

¿Cómo implementarlo?

  • En Laravel: ¡El Middleware para la limitación ya está integrado! Abra app/Http/Kernel.php y busque la clave middlewareGroups['api']. Ya existe 'throttle:api'. La configuración de esta limitación se encuentra en app/Providers/RouteServiceProvider.php en el método configureRateLimiting().

    // app/Providers/RouteServiceProvider.php
    protected function configureRateLimiting()
    {
        RateLimiter::for('api', function (Request $request) {
            return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
        });
    }
    
    // Esto significa: 60 solicitudes por minuto por usuario (si está autenticado) o por dirección IP.

  • En FastAPI: Se utiliza un paquete de terceros, por ejemplo, slowapi.

  • Instalación: pip install slowapi

  • Integración en main.py:
    # main.py
    from slowapi import Limiter, _rate_limit_exceeded_handler
    from slowapi.util import get_remote_address
    from slowapi.errors import RateLimitExceeded
    
    limiter = Limiter(key_func=get_remote_address)
    app = FastAPI(...)
    
    # Conectamos el manejador de errores y el limitador.
    app.state.limiter = limiter
    app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
    
    # Aplicamos a un endpoint específico.
    @router.get("/planets")
    @limiter.limit("5/minute") # 5 solicitudes por minuto
    def get_planets(request: Request):
        # ...
    

4. Mamparos internos: Autorización (¡no confundir con autenticación!)

¿Qué es esto?

  • Autenticación responde a la pregunta "¿Quién eres?".
  • Autorización responde a la pregunta "¿Qué se te permite hacer?".

Por ejemplo, un usuario normal puede ver planetas, pero solo un usuario con el rol de "administrador" puede eliminarlos.

¿Cómo implementarlo?

  • En Laravel: Se utilizan Policies (Políticas) o Gates (Compuertas).

  • Creamos una política: php artisan make:policy PlanetPolicy --model=Planet

  • Describimos las reglas en app/Policies/PlanetPolicy.php:
    class PlanetPolicy
    {
        // Permitir la eliminación solo a usuarios con el rol 'admin'
        public function delete(User $user, Planet $planet): bool
        {
            return $user->role === 'admin';
        }
    }
    
  • Aplicamos la política en el controlador PlanetController.php:

    public function destroy(Planet $planet)
    {
        // Verificamos si el usuario actual tiene derecho a eliminar
        $this->authorize('delete', $planet);
    
        $planet->delete();
        return response()->json(null, 204);
    }
    

  • En FastAPI: La lógica de autorización generalmente se escribe manualmente dentro de los endpoints, utilizando la información del usuario obtenida del token.

# (asumimos que el token tiene un campo 'roles')
def get_current_active_user(token: str = Depends(oauth2_scheme)):
    # ... decodificamos el token y obtenemos el usuario con roles de la BD
    # user = get_user_from_db(username)
    return user # devolvemos el objeto de usuario

@router.delete("/planets/{planet_id}")
def delete_planet(
    planet_id: int,
    current_user: User = Depends(get_current_active_user)
):
    if "admin" not in current_user.roles:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Permisos insuficientes para realizar esta operación",
        )
    # ... lógica de eliminación ...

5. Inspección de cargas y Caja fuerte secreta: Validación y Variables de entorno

Estos dos puntos ya los hemos implementado, pero es importante recalcar su papel en la seguridad.

  • Nunca confíe en los datos entrantes (Validación):

  • Hemos utilizado $request->validate() en Laravel y modelos Pydantic en FastAPI. Esto nos protege de inyecciones SQL (al usar Eloquent/SQLAlchemy) y de datos incorrectos que pueden romper la aplicación. ¡Siempre valide todo lo que viene del exterior!

  • Guarde los secretos en .env (Variables de entorno):

  • Las claves de las bases de datos, las claves secretas para JWT (SECRET_KEY), las claves de servicios de terceros — todo esto nunca debe ir al sistema de control de versiones (Git). Para ello existen los archivos .env, que se añaden a .gitignore.


Cuestionario para afianzar

1. Para proteger contra la interceptación de datos en redes públicas se utiliza:

2. La limitación de la tasa de solicitudes (Rate Limiting) protege principalmente contra:

3. La pregunta "¿Qué se le permite hacer a este usuario?" la resuelve:

4. Las claves secretas de API y las contraseñas de la base de datos deben almacenarse:


🚀 Finalización del curso ¡Felicidades, comandante! Has completado todas las misiones con éxito.

Has pasado de ser un novato que solo había oído hablar de las API a un ingeniero capaz de diseñar, desarrollar, documentar, proteger y probar de forma independiente un servicio web completo utilizando las dos tecnologías más populares en sus respectivos ecosistemas.

Has dominado el lenguaje universal REST, aprendido Laravel y FastAPI y construido un "Centro de Control de Vuelo" para ellos usando JavaScript puro.

Este es un logro enorme. El mundo del desarrollo de API está ahora abierto para ti. Continúa explorando, aprendiendo y construyendo cosas asombrosas.

Fin de la transmisión. 🚀

☄ Apoya la misión

La creación de este tutorial es un viaje largo y complejo que requiere mucho tiempo y energía. Si el material te ha sido útil, puedes ayudar a rellenar los tanques de combustible de nuestra expedición. Cada apoyo es otra órbita hacia nuevos materiales útiles.

Buy Me a Coffee at ko-fi.com ```