Cómo se requiere el Inicio de sesión para los Archivos Multimedia en Django


Estoy sirviendo información "sensible" en PDF descargables y hojas de cálculo dentro de una sección de registro de usuario de un sitio.

¿Hay alguna manera de permitir la autenticación django para proteger este medio sin servirlo (y no tener que iniciar sesión manualmente usando autenticación básica)?

Supongo que hay (dedos cruzados) no una manera de hacerlo con el código psuedo a continuación, pero ayuda a ilustrar mejor el objetivo final.

#urls.py
(r'^protected_media/(?P<filename>.*)$', 'protected_media')

#views.py
from django.contrib.auth.decorators import login_required

@login_required
def protected_media(request, filename):
    # @login_required bounces you out to the login url
    # if logged in, serve "filename" from Apache
Author: TomFuertes, 2009-07-12

4 answers

Me parece que el método que describiste en tu código debería funcionar. Realmente no es diferente de cualquier otro recurso protegido: sus vistas pueden servir archivos de discos, registros de bases de datos, plantillas renderizadas o cualquier cosa. Del mismo modo que el decorador login_required evita el acceso no autorizado a otras vistas, impedirá dicho acceso a su vista que sirve medios protegidos.

¿Me estoy perdiendo algo de su pregunta aquí? Por favor, aclare si esa es la caso.

EDIT: Con respecto al enlace doc de django en su comentario: ese es el método para simplemente servir cualquier archivo de solicitud desde un directorio en particular. Por lo tanto, en ese ejemplo URLS como /site_media/foo.jpg, /site_media/somefolder/bar.jpg buscará automáticamente los archivos foo.jpg y somefolder/bar.jpg en document_root. Básicamente, cada cosa bajo document_root estará disponible públicamente. Eso es obviamente inseguro. Así que evita eso con tu método.

También se considera ineficiente porque django solo está agregando una gran cantidad de sobrecarga cuando todo lo que necesita es algo como Apache para tomar una solicitud de URL y asignarla a un archivo en el disco duro. (No necesita sesiones de django, procesamiento de solicitudes, etc.)

En su caso, esto puede no ser una gran preocupación. Primero, has asegurado la vista. En segundo lugar, depende de sus patrones de uso. ¿Cuántas solicitudes anticipa para estos archivos? Solo estás usando django para autenticación justify ¿eso justifica otros gastos generales? Si no, puede buscar en el servicio de esos archivos con Apache y usando un proveedor de autenticación. Para más información sobre esto, vea la documentación de mod_wsgi:

Hay mecanismos similares disponibles bajo mod_python Creo. (Actualización: acabo de notar la otra respuesta. Por favor, vea la respuesta de Andre para el método mod_python.)

EDICIÓN 2: Con respecto a para el código para servir un archivo, por favor vea este fragmento:

El método send_file utiliza un FileWrapper que es bueno para enviar archivos estáticos grandes de vuelta (no lee todo el archivo en la memoria). Necesitará cambiar el content_type dependiendo del tipo de archivo que esté enviando (pdf, jpg, etc.).

 9
Author: ars,
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
2009-07-11 21:48:10

Lee este ticket de Django para más información. Empieza desde abajo para ahorrarte algo de tiempo. Parece que acaba de perderse entrar en Django 1.2, y supongo que tampoco está en 1.3.

Para Nginx, encontré este fragmento de Django que aprovecha el encabezado X-Accel-Redirect, pero aún no lo he probado.

 4
Author: Dave,
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
2010-12-07 19:42:50

Actualmente se está estudiando un servicio más eficiente de archivos estáticos a través de Django como parte del proyecto SOC de Google. Para WSGI se utilizará wsgi.extensiones file_wrapper para WSGI si están disponibles, como lo está para mod_wsgi, y req.sendfile () si usa mod_python. También admitirá la devolución de encabezados como 'Location', 'X-Accel-Redirect' y otros, que diferentes mecanismos de alojamiento web y servidores proxy aceptan como un medio para servir archivos estáticos donde la ubicación está definida por un backend aplicación web, que no es tan eficaz como front end para servir archivos estáticos.

No estoy seguro de si hay una página de proyecto para esto en Django wiki en algún lugar o no, pero los cambios de código están siendo confirmados en la rama branches/soc2009/http-wsgi-improvements del repositorio de código fuente de Django.

No es necesario esperar estrictamente a que las cosas. Es solo poner una interfaz limpia y portátil en su lugar a través de los diferentes mecanismos. Si se utiliza nginx como front end en frente de Apache / mod_wsgi, puedes usar X-Accel-Redirect ahora. Si usa Apache / mod_wsgi 3.0 y el modo demonio, puede usar Location ahora, pero necesita asegurarse de configurar Apache correctamente. Alternativamente, puede implementar su propio envoltorio de middleware WSGI alrededor de la aplicación Django que busca algún encabezado de respuesta propio para indicar el archivo que se devolverá y que utiliza wsgi.file_wrapper para devolver eso en lugar de la respuesta real devuelta por Django.

Por cierto, el gancho de autenticación los mecanismos listados para mod_python y mod_wsgi por otros usarían autenticación básica HTTP, que no es lo que querías. Esto supone que desea que los archivos estén protegidos por el mecanismo de inicio de sesión basado en formularios de Django utilizando cookies y sesiones de backend.

 3
Author: Graham Dumpleton,
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
2009-07-12 04:01:18

Si entiendo su pregunta correctamente, ¿desea restringir el acceso a los archivos que no están siendo servidos por Django, por ejemplo, con un servidor Apache?

Lo que se requiere entonces es alguna forma para que este servidor Apache utilice Django como fuente de autenticación.

Este fragmento de django describe dicho método. Crea un manejador de acceso en Django que es usado por Apache cuando viene una solicitud para un archivo estático que necesita ser protegido:

<Location "/protected/location">
            PythonPath "['/path/to/proj/'] + sys.path"  
            PythonOption DJANGO_SETTINGS_MODULE myproj.settings
        PythonOption DjangoPermissionName '<permission.codename>'
        PythonAccessHandler my_proj.modpython #this should point to accesshandler
            SetHandler None
</Location>

Esperanza esto ayuda, el fragmento se publicó hace un tiempo, por lo que las cosas podrían haber cambiado entre las versiones de Django:)

 1
Author: Andre Miller,
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
2009-07-11 21:28:57