2012-05-24 3 views
8

Estoy trabajando para desarrollar un sitio web que permita a los clientes iniciar sesión y ver varios PDFs guardados en el servidor. Estos archivos PDF serán únicos para el cliente y no deberían ser accesibles para alguien que no esté conectado. Obtener los archivos en el servidor no debería ser un problema, simplemente no estoy seguro de cómo servirlos a los usuarios finales.Creación de un servidor de alojamiento de archivos seguro para archivos PDF

Implementé este tipo de cosas con los datos de SQL servers en lugar de archivos, por lo que no estoy del todo seguro de cuál es la forma más efectiva de hacerlo.

El sitio web está en un LAMP y mi experiencia mínima está en PHP (pero si un marco de trabajo u otro idioma lo hace más fácil, puedo aprenderlo).

Probablemente estoy en mi cabeza, pero normalmente lo estoy, por lo que cualquier aportación sería genial.

Respuesta

9

Coloque los archivos fuera de la raíz web. Luego, usando PHP pasa el archivo a través de un script. De esta forma, nadie puede vincular el archivo directamente y eludir tus controles. (Naturalmente, asegúrese de que la secuencia de comandos que hace esto solo después de verificar que el usuario tiene permiso para recuperar ese archivo).

PHP muestra:

<?php 
    session_start(); 
    if (!isset($_SESSION['authenticated'])) { 
     exit; 
    } 
    $file = '/path/to/file/outside/www/secret.pdf'; 

    header('Content-Description: File Transfer'); 
    header('Content-Type: application/octet-stream'); 
    header('Content-Disposition: attachment; filename=' . basename($file)); 
    header('Content-Transfer-Encoding: binary'); 
    header('Expires: 0'); 
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
    header('Pragma: public'); 
    header('Content-Length: ' . filesize($file)); 
    ob_clean(); 
    flush(); 
    readfile($file); 
    exit; 
?> 
+0

¿No debería 'session_start();' cargar? Supongo que se supone que funciona con las sesiones. –

+0

En realidad, sí, debería ser. Estaba tan concentrado en el concepto central que no proporcioné un ejemplo verdaderamente completo. Voy a arreglar eso ahora ... –

+0

Solo marcando ;-) –

4

La manera más fácil es dar a estos archivos de nombres de archivo largos al azar (por ejemplo, 20 caracteres aleatorios). Técnicamente, cualquiera podrá acceder a ellos, pero no será posible adivinar la URL, por lo que solo las personas autorizadas tendrán acceso.

Alternativamente John Conde ya delineó una forma de servir un archivo desde un script PHP. Se incurrirá en una pequeña penalización de rendimiento, pero será tan seguro como su código. Lo único que puedo agregar es que si no puede ubicarlos fuera de webroot, entonces es posible que pueda usar .htaccess para evitar que las personas accedan a los archivos directamente.

+1

Sugeriría GUID. Esto todavía tiene el problema de que puedo hacer ping al servidor hasta que obtengo algo interesante, aunque puedes hacer que las posibilidades de éxito sean infinitamente pequeñas. Apoyo el uso de .htaccess para bloquear el acceso a la carpeta. – zebediah49

+1

@ zebediah49 - Es una posibilidad, pero [hay trampas] (http://blogs.msdn.com/b/oldnewthing/archive/2012/05/23/10309199.aspx) que debe tener en cuenta. Simplemente generar una cadena aleatoria es más seguro. Y, si quiere estar seguro al 110%, use un generador de números aleatorios criptográficamente fuerte. –

+0

Muy interesante, gracias. Escogí el GUID por extensión, pero aún así evitaría usar URL accesibles públicamente, pero ese es un muy buen punto. – zebediah49

2

John publicó la forma correcta y correcta de hacerlo, así que estoy agregando la alternativa (probablemente inferior): Servirlo desde la base de datos. Solo tiene una columna BLOB para el PDF y lea/almacene los datos del archivo de la base de datos. Terminará con una mesa bastante grande, pero funcionará. Servir requiere establecer el mismo header() s que publicó John, simplemente envíe los datos de la base de datos en lugar de enviarlos desde el archivo.

Esto tiene la ventaja de no tener que asegurarse de que no tiene colisiones de nombre de archivo, etc.

Cuestiones relacionadas