简体   繁体   English

使用 Dokku 制作 Django 用户上传的媒体文件

[英]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)

Let's do it by yourself!让我们自己做吧!

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:所以,你需要:

  1. Add a path, something like /profiles/<int:user_id>/image/ in your urls.py在你的urls.py添加一个路径,比如/profiles/<int:user_id>/image/
  2. Use this link with a proper user_id in your front-end (change a needed template)在前端使用此链接和适当的user_id (更改所需的模板)
  3. Write a class-based or function-based view for this endpoint, as usual, check the 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参数,检查请求中的身份验证,将请求中的用户与用户实例中的用户进行比较,也许还有其他事情。
  4. Response with 401 Not Authorized when you have an unauthorized request.当您有未经授权的请求时,回复401 Not Authorized
  5. Response with FileResponse in OK.用 FileResponse 响应 OK。
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.

相关问题 如何在Django中对用户上传的文件应用读/写权限 - How to apply read/write permissions to user-uploaded files in Django 如何在 Django 中提供用户上传的 pdf 文件? - How to Serve User-Uploaded pdf Files in Django? Django - 在生产中提供媒体/上传的文件 - Django - Serving MEDIA/uploaded files in production 如何链接到Django模板中的用户上传的个人资料图片(ImageField)? - How to link to user-uploaded profile pictures (ImageField) in Django templates? Django在openshift中提供媒体文件(用户上传的文件) - Django serving media files (user uploaded files ) in openshift Flask - 将用户上传的图像提供给网页 - Flask - Serving user-uploaded images to the webpage 解除用户上传的 PDF 的最佳方法 - Best way to disarm user-uploaded PDFs 如何将特定用户分配给用户上传的文件,以便他们可以对其进行修改/删除(Django + Apache) - How do I assign specific users to a user-uploaded file so they can modify it/delete it (Django + Apache) 如何放置一种格式,在该格式中分析用户上传的文件,然后将其显示在新的url上? - How can I put in a form where user-uploaded files are parsed and then displayed on a new url? Django-如何在生产中为用户上传的内容提供服务 - Django - How to serve user uploaded content in production
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM