2016-09-28 9 views
0

Djangoには、ログインしたユーザーのみのメディアファイル(ユーザーアップロードファイルなど)を配信したいと考えています。私のサイトはかなりトラフィックが少ないので、私は物事を単純に保ち、Nginxにファイルを提供するときにはdjango-sendfileを使わないでください。代わりに私はDjango/Gunicornに仕事をさせます。私にとっては、これはずっと簡単で、トラフィックの少ないサイトではこれはもっと安全です。保護されたメディアファイルをdjangoで配信する

しかし、ファイルの格納場所を整理する最良の方法は何ですか?メディアファイルはすべてMEDIA_ROOT以下に格納され、このディレクトリはNginxが運用しています。ファイルをMEDIA_ROOT/protected/にアップロードすると、Nginxにサブディレクトリprotectedのファイルを提供しないように指示する必要があります。

これは良い考えですか? Nginxのアクセス先で最初に/media/にアクセスしてから、サブディレクトリ/media/protected/を保護するのは危険です。保護されたファイルを格納するためにサブディレクトリMEDIA_ROOTを使用しない方が良いのではないでしょうか?

しかし、私は私のモデルでは、この間に合わせと-ような何かしようとした場合:

upload_to='../protected/documents/%Y/%m/' 

をDjangoは文句:

SuspiciousFileOperation at /admin/core/document/add/ 
The joined path (/home/me/projects/project/protected/documents/2016/09/test.file) is located outside of the base path component (/home/me/projects/project/media) 

だから私の事は、「去る」ことをお勧めではありませんMEDIA_ROOT

保護されたメディアファイルを保存して配信する最適なソリューションは何ですか?

答えて

0

私は今、次の解決策を考え出した:どちらか私は何私のモデルで

MEDIA_ROOT = "/projects/project/media/" 
MEDIA_URL = "/media/ 

::私は私のDjangoの設定でこれを持って

document = models.FileField(upload_to="public/documents") 

または

document = models.FileField(upload_to="protected/documents") 

このように、私は今、私のメディアファイルディレクトリに2つのサブディレクトリ 'public'と 'protected'を持っています。

NginxまたはDjangos開発サーバーは、 'public'サブディレクトリ内のファイルのみを処理します。

if os.environ["ENVIRONMENT_TYPE"] == 'development': 
    urlpatterns += static(settings.MEDIA_URL + "public/", document_root=settings.MEDIA_ROOT + "public/") 

そして、nginxのための

(生産に使用):Djangos開発サーバーの場合

私は保護されたドキュメントを提供したい

location /media/public/ { 
    alias /projects/project/media/public/; 
} 

、私は次の操作を行います

In urls.py:

url(r'^media/protected/documents/(?P<file>.*)$', core.views.serve_protected_document, name='serve_protected_document'), 

そしてviews.pyに:

@login_required() 
def serve_protected_document(request, file): 
    document = get_object_or_404(ProtectedDocument, file="protected/documents/" + file) 

    # Split the elements of the path 
    path, file_name = os.path.split(file) 

    response = FileResponse(document.file,) 
    response["Content-Disposition"] = "attachment; filename=" + file_name 

    return response 

私は、任意のコメントをいただければ幸いです!これを実装するより良い方法はありますか?

+0

私はどんな公共のメディアを持っていないことを除いて、私は好きではないであろうと、同じ問題への解決策を探していますへのあなたの視野ファイルを提供するためにDjangoを悪用します。しかし、現時点ではただ一つの発言。ファイルレスポンスを使用する前にファイルを開くべきではありませんか? https://docs.djangoproject.com/en/1.10/ref/request-response/#fileresponse-objects – texnic

+0

@texnic私の答えをチェックする –

0

私の答えhereを確認できます。 nginxサーバーで利用可能な拡張子sendfileを使用すると、メディアファイル(大容量のファイルでも可)を直接表示することはできません。最初nginxの設定の下に追加

location /projects/project/media/{ 
    # this path is not public 
    internal; 
    # absolute path 
    alias /projects/project/media/; 
} 

変更

@login_required 
def serve_protected_document(request, file): 
    document = get_object_or_404(ProtectedDocument, file="protected/documents/" + file) 

    # Split the elements of the path 
    path, file_name = os.path.split(file) 

    response = HttpResponse() 
    response["Content-Disposition"] = "attachment; filename=" + file_name 
    # using http://github.com/instapk/django-fileprovider 
    response["X-File"] = document.name 
    return response 
関連する問題