Proteger las descargas en el servidor remoto

3 minutos de lectura

avatar de usuario
usuario1446650

Tengo 2 servidores. En el servidor 1 tengo un sitio web de WordPress. En el Servidor 2 tengo archivos .zip grandes que quiero que los miembros del sitio de WordPress puedan descargar.

¿Cómo autentico a estos usuarios para que solo las personas que son miembros del sitio web puedan descargar archivos del segundo servidor?

¿Es posible usar PHP para que solo los remitentes de mi dominio tengan acceso a los archivos?

Nota: Los enlaces para descargar los archivos están protegidos en el sitio de wordpress para que los usuarios que no hayan iniciado sesión sean redirigidos a una página de unión. Sin embargo, los miembros actuales y anteriores aún conocerán el directorio donde se encuentran las descargas y posiblemente podrían descargar los archivos o compartir los enlaces.

  • Tenga cuidado con el uso de tokens basados ​​en la marca de tiempo actual. Cuantas cosas pueden suceder al mismo tiempo, es realmente una muy mala idea usar tokens basados ​​en el tiempo, a menos que tenga algún prefijo en esa cadena y debe ser único. Pruebe algo con identificaciones únicas generadas por su base de datos, es totalmente seguro.

    – devasia2112

    9 de junio de 2012 a las 22:10


Hay varias maneras de hacer esto. La forma más segura sería tener alguna comunicación de back-end entre el Servidor 1 y el Servidor 2. Pero aquí hay una alternativa fácil:

Servidor 2: descargar.php

<?PHP
 $file = $_GET['f'];
 $code = $_GET['c']; 
 $ip = $_SERVER['REMOTE_ADDR'];

 if ($code != md5($ip . 'salt')) {
    die('authentication denied');
 }

 if(!file)
 {
     die('file not found');
 }

 // Set headers
 header("Cache-Control: public");
 header("Content-Description: File Transfer");
 header("Content-Disposition: attachment; filename=$file");
 header("Content-Type: application/zip");
 header("Content-Transfer-Encoding: binary");

 // Read the file from disk
 readfile('/files/downloads/' . $file);

?>

Servidor 1: enlace de descarga

<?PHP
 echo '<a href="http://server2.com/download.php?f=text.txt&c=" . md5($_SERVER["REMOTE_ADDR'] . 'salt') / '">Download File</a>';
?>

Este sistema funciona creando un enlace que solo se puede utilizar en la IP para la que se generó. Entonces, un usuario registrado no puede compartir el enlace en otro lugar. No es lo más seguro, pero es fácil de implementar y funcionará.

  • ¡Gracias por la respuesta! Para el código del servidor 2, ¿debería colocarse en un dominio, o simplemente puede cargarlo directamente en la IP del servidor? También asumo que la sección “Leer el archivo del disco”: me gustaría que los archivos se ubicaran en el directorio readfile (‘mi/descarga/ruta/aquí’?

    – usuario1446650

    10 de junio de 2012 a las 23:22

  • El código para server2 solo necesita ser accesible públicamente. Y sí, cambie “/archivos/descargas/” para que se ajuste a sus necesidades. Por favor marque la respuesta como aceptada.

    – Patricio Lorio

    11 de junio de 2012 a las 18:43


Una buena solución puede ser usar un sistema de fichas basado en la hora actual. Puede tomar la hora actual del día y analizarla con un poco de sal, y ponerla en la cadena de consulta como token. Entonces, el script php en el segundo servidor puede verificar si el hash de la cadena de consulta es el mismo, como el hash generado para la hora actual del día con la misma sal en el lado del servidor.

Para asegurarse de que el usuario no llegue a la hora de cambio de hora, también puede verificar el hash de la hora anterior.

Le asegura que la URL del archivo no estará disponible durante más de dos horas con un tiempo garantizado de disponibilidad de una hora.

En el servidor 1:

<?php
echo '<a href="https://stackoverflow.com/questions/10964399/server2.com/download.php?token=".md5(date('G')+'secret_word').'&file=file.zip">Link</a>';
?>

En el servidor 2:

<?php
current_hour_hash = md5( date('G').'secret_word' );
previous_hour_number = ( int(date('G')) - 1 ) % 24;
previous_hour_hash = md5( str(previous_hour_number).'secret_word' );
if($_GET['token']!= current_hour_hash and $_GET['token']!= previous_hour_hash){
    die();
}else{
    ... //code sending file here
}

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad