2

私は Apache を使用して Django アプリをデプロイし、デコレーターを使用してほとんどのビューで認証を確認しました。

@custom_decorator
def myView(request):
    bla bla bla...

Django に付属する @login_required デコレーターではありませんが、特定のグループのユーザーのみにアクセスを許可することを除いて、ほとんど同じです。これは意図したとおりに機能します。

また、次のように、メディア (ユーザーがアップロードした) ファイルを Apache で提供しています。

Alias /media /path/to/media
<Directory /path/to/media>
     Require all granted
</Directory

メディア ファイルには問題なくアクセスできますが、問題は、ログインしていなくても次のように URL を手動で入力するだけでアクセスできることです。

mySite/media/myFile.png

できればカスタム デコレータを使用して、メディア ファイルへのアクセスを制限する方法はありますか?

同様の質問に出くわしました: How do you Require Login for Media Files in Djangoですが、残念ながら答えは私の頭をはるかに超えていました。

前もって感謝します!

4

3 に答える 3

1

さて、@ MoinuddinQuadriの回答とリンクに基づいて、最も簡単な解決策は、通常のDjangoビューを使用してファイルを提供し、次のように目的のデコレータを適用することです。

@custom_decorator
viewFile(request, objectID):
    object = MyModel.object.get(id = objectID)
    return HttpResponse(object.file, content_type = "image/png")

(私の場合、モデルに関連する FileField を提供したかったので、ビューではファイル名の代わりにオブジェクトの ID を渡しました)。

また、Apache conf 内の対応するコードをコメントアウトしました。

### Alias /media /path/to/media
### <Directory /path/to/media>
###     Require all granted
###</Directory

メディア ファイルの URL の代わりに新しいビューを使用するようにいくつかのテンプレートを変更する必要がありましたが、現在は意図したとおりに機能し、ログインしていないユーザーはロックアウトされています。

ただし、これは Apache を使用してファイルを提供するのではなく、Django 自体を使用します。これは docsによると、非効率的であり、推奨されません。

理想的には、引き続き Apache を使用してファイルを提供し、ビューを使用してそのアクセスを保護する必要があります。そのためには、Apache のmod_xsendfileを使用するか、前述のモジュールのラッパーであるDjango Sendfileを使用できます。

私は後者を試しましたが、残念ながらASCII以外の文字を含むファイル名には問題があります。私のターゲットはスペイン語を話すユーザーであるため、少なくとも今のところ、Django でファイルを提供するという手段に頼らなければなりませんでした。

于 2016-11-20T19:14:53.247 に答える
1

「 Django で保護されたメディア ファイル」の投稿で解決策 #1 を使用しました。ここでは、「予測できない URL」と「X-Sendfile」という 2 つの解決策についても説明していますが、ここで説明しているのは私の選択です。

@Sauventが述べたように、これにより、ファイルはWebサーバー(Apacheなど)ではなくDjangoによって提供されます。ただし、大量のトラフィックや大きなファイルを扱っていない場合は、すばやく簡単に行うことができます。

基本的に、urls.py に以下を追加します。

@login_required
def protected_serve(request, path, document_root=None, show_indexes=False):
    return serve(request, path, document_root, show_indexes)

urlpatterns = patterns('',
    url(r'^{}(?P<path>.*)$'.format(settings.MEDIA_URL[1:]), protected_serve, {'document_root': settings.MEDIA_ROOT}),
)

私の場合、ディレクトリの設定が異なり、Login Required Middleware を使用してどこでもログインが必要であることを確認するため、次のように編集しました ( Django: login_required デコレータをサイト全体 (静的メディアを除く) に適用するにはどうすればよいですか? :

urlpatterns = patterns('',
    url(r'^media/(?P<path>.*)$', "django.views.static.serve", {'document_root': settings.MEDIA_ROOT}),
)
于 2018-12-02T08:06:20.933 に答える