[英]Django user-uploaded media files in production with Dokku
I would like to serve user uploaded media files using nginx on the same host as the Django application rather than a CDN or S3 or similar.我想在与 Django 应用程序相同的主机上使用 nginx 为用户上传的媒体文件提供服务,而不是 CDN 或 S3 或类似的。
The django-private-storage library can be used to protect media files behind a login: https://github.com/edoburu/django-private-storage django-private-storage 库可用于保护登录后的媒体文件: https : //github.com/edoburu/django-private-storage
I am deploying my Django application with Dokku.我正在使用 Dokku 部署我的 Django 应用程序。
Dokku says that dokku persistant storage plugin should be used to allow for user uploads to be persisted on the host. Dokku 说应该使用 dokku 持久存储插件来允许用户上传在主机上持久化。 https://dokku.com/docs~v0.9.2/advanced-usage/persistent-storage/
https://dokku.com/docs~v0.9.2/advanced-usage/persistent-storage/
My confusion is that django-private-storage requires you to edit the config for nginx.我的困惑是 django-private-storage 要求您编辑 nginx 的配置。 Specifically, it requires you to set the location of the private media being served to be internal.
具体来说,它要求您将提供服务的私有媒体的位置设置为内部。 So that the URL cannot be accessed from the outside by a user who isn't logged in.
这样未登录的用户就无法从外部访问该 URL。
The dokku docs don't explain how to use persistant storage behind an application login. dokku 文档没有解释如何在应用程序登录后使用持久存储。 Do I actually need django-persistant-storage to be able to write user uploaded media?
我真的需要 django-persistant-storage 才能编写用户上传的媒体吗?
How can I combine these solutions so that my application, which is inside a container, can read and write media files, which media files are served by nginx, and served at an internal location that can only be accessed by a user who is logged into the application?我如何组合这些解决方案,以便我的容器内的应用程序可以读取和写入媒体文件,哪些媒体文件由 nginx 提供,并在只能由登录用户访问的内部位置提供应用程序?
Updates (Oct 2021) I am able to deploy my app, upload files and access them at the appropriate URL.更新(2021 年 10 月)我能够部署我的应用程序、上传文件并通过适当的 URL 访问它们。 But I haven't been able to protect them against unauthenticated access.
但是我无法保护它们免受未经身份验证的访问。
I haven't yet used django-private-storage or dokku persistant storage.我还没有使用 django-private-storage 或 dokku 持久存储。 Once the files are inaccessible I plan to follow these steps to allow authenticated access: https://b0uh.github.io/protect-django-media-files-per-user-basis-with-nginx.html
一旦文件无法访问,我计划按照以下步骤允许经过身份验证的访问: https : //b0uh.github.io/protect-django-media-files-per-user-basis-with-nginx.html
I created a file my_conf.conf saved to /home/dokku/backend/nginx.conf.d我创建了一个文件 my_conf.conf 保存到 /home/dokku/backend/nginx.conf.d
which contains其中包含
location /protected/ {
internal;
alias /home/dokku/backend/;
}
and then rebooted Nginx然后重新启动 Nginx
I can't actually see the images anywhere on host, but if I run dokku enter backend
then my files are there in the container under '/mediafiles/testuploads/'我实际上无法在主机上的任何地方看到图像,但是如果我运行
dokku enter backend
那么我的文件就在容器中的“/mediafiles/testuploads/”下
Here is settings.py这是settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'mediafiles')
MEDIA_URL = '/media/'
and models.py和模型.py
class User(AbstractUser):
profile_image = models.ImageField(upload_to='testuploads/', null=True)
You can serve your profile images with your custom view that checks auth!您可以使用检查身份验证的自定义视图来提供您的个人资料图片!
You may implement the needed feature without additional dependencies.您可以在没有附加依赖项的情况下实现所需的功能。 As a bonus, you will understand the whole process.
作为奖励,您将了解整个过程。
So, you need to:所以,你需要:
/profiles/<int:user_id>/image/
in your urls.py
urls.py
添加一个路径,比如/profiles/<int:user_id>/image/
user_id
in your front-end (change a needed template)user_id
(更改所需的模板)user_id
parameter, check the auth in request, compare user in request with the user in the user instance and maybe something else.user_id
参数,检查请求中的身份验证,将请求中的用户与用户实例中的用户进行比较,也许还有其他事情。401 Not Authorized
when you have an unauthorized request.401 Not Authorized
。from django.http import FileResponse
response = FileResponse(open('myfile.png', 'rb'))
use your user.profile_image
property使用您的
user.profile_image
属性
Theoretically, if the user doesn't know the old path to /media/testuploads/filename.ext
this file is " not shared ".理论上,如果用户不知道
/media/testuploads/filename.ext
的旧路径, /media/testuploads/filename.ext
该文件是“不共享的”。
But if you want to be sure - don't serve /media/
folder with NGINX or exactly /media/testuploads/
path if you want to serve another media files ( return 401 https://$host$request_uri;
in NGINX config in the needed block).但是,如果你要确保-不服务
/media/
nginx的文件夹或正好/media/testuploads/
如果你想为其他媒体文件(路径return 401 https://$host$request_uri;
在NGINX配置在所需的块)。 Such changes need NGINX to be reloaded.此类更改需要重新加载 NGINX。
Watch view caching in the next seasons 😀 to improve the performance.观看下一季的视图缓存😀以提高性能。 But the browser will cache the image if it works in default settings.
但是如果它在默认设置下工作,浏览器将缓存图像。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.