Me gustaría servir archivos multimedia cargados por el usuario usando nginx en el mismo host que la aplicación Django en lugar de un CDN o S3 o similar.
La biblioteca django-private-storage se puede usar para proteger archivos multimedia detrás de un inicio de sesión: https://github.com/edoburu/django-private-storage
Estoy implementando mi aplicación Django con Dokku.
Dokku dice que el complemento de almacenamiento persistente de dokku debe usarse para permitir que las cargas de los usuarios persistan en el host. https://dokku.com/docs~v0.9.2/uso-avanzado/almacenamiento-persistente/
Mi confusión es que django-private-storage requiere que edites la configuración para nginx. Específicamente, requiere que configure la ubicación de los medios privados que se sirven para que sean internos. Para que un usuario que no haya iniciado sesión no pueda acceder a la URL desde el exterior.
Los documentos de dokku no explican cómo usar el almacenamiento persistente detrás del inicio de sesión de una aplicación. ¿Realmente necesito django-persistant-storage para poder escribir medios cargados por el usuario?
¿Cómo puedo combinar estas soluciones para que mi aplicación, que está dentro de un contenedor, pueda leer y escribir archivos multimedia, qué archivos multimedia son servidos por nginx y servidos en una ubicación interna a la que solo puede acceder un usuario que haya iniciado sesión? ¿la aplicación?
Actualizaciones (octubre de 2021) Puedo implementar mi aplicación, cargar archivos y acceder a ellos en la URL adecuada. Pero no he podido protegerlos contra el acceso no autenticado.
Todavía no he usado django-private-storage o almacenamiento persistente dokku. Una vez que los archivos sean inaccesibles, planeo seguir estos pasos para permitir el acceso autenticado: https://b0uh.github.io/protect-django-media-files-per-user-basis-with-nginx.html
Creé un archivo my_conf.conf guardado en /home/dokku/backend/nginx.conf.d
que contiene
location /protected/ { internal; alias /home/dokku/backend/; }y luego reinició Nginx
En realidad, no puedo ver las imágenes en ninguna parte del host, pero si ejecuto dokku enter backend , mis archivos están allí en el contenedor en '/mediafiles/testuploads/'
Aquí está la configuración.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'mediafiles') MEDIA_URL = '/media/'y modelos.py
class User(AbstractUser): profile_image = models.ImageField(upload_to='testuploads/', null=True)¡Puede servir sus imágenes de perfil con su vista personalizada que verifica la autenticación!
Puede implementar la característica necesaria sin dependencias adicionales. Como beneficio adicional, comprenderá todo el proceso.
Entonces, necesitas:
/profiles/<int:user_id>/image/ en su urls.pyuser_id adecuado en su interfaz (cambie una plantilla necesaria)user_id , verifique la solicitud de autenticación, compare el usuario en la solicitud con el usuario en la instancia de usuario y tal vez algo más.401 Not Authorized cuando tenga una solicitud no autorizada. from django.http import FileResponse response = FileResponse(open('myfile.png', 'rb')) use su propiedad user.profile_image
En teoría, si el usuario no conoce la ruta anterior a /media/testuploads/filename.ext , este archivo " no se comparte ".
Pero si quiere estar seguro, no sirva la carpeta /media/ con NGINX o exactamente la ruta /media/testuploads/ si desea servir otros archivos multimedia ( return 401 https://$host$request_uri; en la configuración de NGINX en el bloque necesario). Dichos cambios necesitan que se vuelva a cargar NGINX.
Mire ver el almacenamiento en caché en las próximas temporadas 😀 para mejorar el rendimiento. Pero el navegador almacenará en caché la imagen si funciona en la configuración predeterminada.