PHP: ¿Cómo puedo bloquear el acceso directo a la URL de un archivo, pero aún permitir que sea descargado por usuarios registrados?


Tengo un sitio web donde los usuarios deberían poder iniciar sesión y escuchar una canción (un mp3 auto-creado). Quiero hacerlo para que el usuario registrado pueda escuchar / descargar / lo que sea, y el archivo debe residir en el servidor (no debe almacenarse en la base de datos MySQL), pero no puede ser accedido por los no usuarios que tienen la ruta a la URL.

Por ejemplo: digamos que mi mp3 se encuentra en mysite.com/members/song.mp3 Si ha iniciado sesión, debería poder ver el mysite.com/members/index.php página, que permitirá el acceso al archivo song. mp3. Si no ha iniciado sesión, el mysite.com/members/index.php la página no le mostrará el archivo song. mp3, y el enlace directo a él no debe otorgar acceso.

Estoy bastante seguro de que esto se hace a través de htaccess, y ya he hecho un montón de búsquedas en Google, y buscado aquí. Las dos respuestas más cercanas que encontré fueron esta guía htaccess http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks / y este bloque de pregunta de StackOverflow acceso directo a un archivo a través de http pero permitir php script access pero no responder a todas mis preguntas para cumplir con mis criterios. ¿Qué me estoy perdiendo?

Author: Community, 2011-08-20

3 answers

En la carpeta miembroscrear nueva carpeta archivos, mover aquí todas sus canciones, crear nuevo .htaccess archivo y añadir las siguientes líneas:

Order Deny,Allow
Deny from all


En la carpeta miembros crear archivo get_song.php y agregue el siguiente código:

if( !empty( $_GET['name'] ) )
{
  // check if user is logged    
  if( is_logged() )
  {
    $song_name = preg_replace( '#[^-\w]#', '', $_GET['name'] );
    $song_file = "{$_SERVER['DOCUMENT_ROOT']}/members/files/{$song_name}.mp3";
    if( file_exists( $song_file ) )
    {
      header( 'Cache-Control: public' );
      header( 'Content-Description: File Transfer' );
      header( "Content-Disposition: attachment; filename={$song_file}" );
      header( 'Content-Type: application/mp3' );
      header( 'Content-Transfer-Encoding: binary' );
      readfile( $song_file );
      exit;
    }
  }
}
die( "ERROR: invalid song or you don't have permissions to download it." );


Y ahora, puede usar esta URL para obtener el archivo de la canción:
http://mysite.com/members/get_song.php?name=my-song-name

 56
Author: B7ackAnge7z,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-19 21:45:42

Lo único que puedes hacer para esto vía .htaccess es requerir un referer que viene de su sitio, y NO es seguro. es más que trivial falsificar un referente y cualquiera podría chupar su sitio seco.

La ÚNICA manera de que solo los usuarios logueados descarguen el archivo es colocando el archivo FUERA de su webroot y teniendo un acceso mediato de script PHP. En resumen:

if (is_logged_in()) {
   readfile($name_of_file);
} else {
   die("Access denied");
}
 7
Author: Marc B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-19 20:44:37

¿Está utilizando un lenguaje de scripting como PHP para manejar su sitio web? si es así, entonces la mejor manera es crear un script que maneje la "entrega" del contenido. Guarde el contenido en un directorio protegido, es decir, encima de su carpeta http o www. Luego, cuando el usuario inicie sesión, el enlace a su contenido se vería así:

Http://yoursite.com/listen.php?song_id=xxx

El script localizará la canción requerida por el id y luego presentará los datos al usuario

 3
Author: Nick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-19 20:43:07