Inicio » Blog »

21 abril, 2025

Cómo controlar descargas seguras en Laravel paso a paso

#Laravel

Controlar las descargas de archivos en Laravel de forma segura, dinámica y profesional, usando roles de usuario, claves únicas (UUID), almacenamiento en caché

Cómo controlar descargas seguras en Laravel paso a paso

Suscríbete a nuestro canal en Youtube

Suscríbirse

¿Quieres evitar que compartan tus enlaces de descarga?

En este artículo aprenderás cómo controlar las descargas de archivos en Laravel de forma segura, dinámica y profesional, usando roles de usuario, claves únicas (UUID), almacenamiento en caché y cabeceras HTTP.


🔍 Objetivo del método

El método downloadCourse($key) permite entregar un archivo a usuarios autenticados, evitando descargas repetidas, bloqueando el uso compartido de enlaces y registrando cada descarga válida.


1️⃣ Verificar autenticación, rol y estado del usuario

Antes de permitir la descarga, se verifica que el usuario cumpla tres condiciones:

if (Auth::check() && Auth::user()->hasRole('curso') && Auth::user()->active) 

✅ ¿Qué verifica esto?

  • Que el usuario esté logueado (Auth::check()).

  • Que tenga el rol "curso", que puedes definir con un sistema de permisos.

  • Que su cuenta esté activa, es decir, no suspendida o bloqueada.

Esto es crucial para restringir el acceso solo a usuarios autorizados.


2️⃣ Buscar el archivo usando una clave única

Cada archivo tiene una clave de descarga única (descarga_key). El sistema la usa para identificar el curso que se desea descargar.

$course = Course::whereDescarga_key($key)->first(); 

🛑 Si el curso no se encuentra:

if (!$course) {
    return redirect()->back()->withSuccessMessage("El archivo no existe");
}

Se envía al usuario un mensaje amigable. Esto evita errores graves o rutas inválidas.


3️⃣ Limitar descargas con Cache: solo una cada 60 segundos

Se crea una clave de caché única para usuario y curso:

$cacheKey = "descarga_{$user->id}_{$course->id}"; 

Luego se verifica si esa clave ya existe:

if (Cache::has($cacheKey)) {
    return redirect()->back()->withErrors("Debes esperar un momento antes de volver a descargar.");
}

Si no existe, se guarda por 60 segundos:

Cache::put($cacheKey, true, now()->addSeconds(60)); 

🕒 ¿Para qué sirve esto?

  • Evita que el usuario descargue repetidamente de forma accidental.

  • Protege el servidor de peticiones excesivas.

  • Mejora la experiencia general del sistema.


4️⃣ Registrar la descarga y generar una nueva clave (UUID)

Cada descarga exitosa se registra con un contador:

$course->increment('descarga_valida'); 

Y luego se actualiza la clave de descarga:

$course->descarga_key = Str::uuid()->toString();
$course->save(); 

🔐 ¿Por qué regenerar la clave?

  • Evita que el enlace pueda ser compartido o reutilizado.

  • El próximo intento de descarga requerirá una nueva clave.

  • Aumenta la seguridad del sistema de entrega de archivos.


5️⃣ Descargar el archivo con cabeceras de seguridad

Finalmente, se entrega el archivo con una respuesta de tipo descarga:

return response()->download( 
    public_path("descargas20/{$course->urlfile}"),
    null,
    [
        'Cache-Control' => 'no-cache, no-store, must-revalidate',
        'Pragma' => 'no-cache',
        'Expires' => '0',
    ]
); 

📦 ¿Qué hacen estas cabeceras HTTP?

  • no-cache: el navegador no debe almacenar una copia del archivo.

  • must-revalidate: fuerza una nueva solicitud si se vuelve a acceder.

  • Esto asegura que siempre se descargue directamente del servidor.


Leido 573 veces | 0 usuarios

Código fuente no disponible.

Compartir link del tutorial con tus amigos


Laravel Página Web Administrable

USD 37.00

Descarga del código fuente

Laravel Página Web Administrable

Codea Applications

México, Colombia, España, Venezuela, Argentina, Bolivia, Perú