If you build intranets in django, you have probably already experienced the issue of how to secure media files so they weren't available from outside of system.
In this article I will introduce three ways of solving this issue.
1) Serving media files with django
Easy and secure solution is to serve media files by django in the same way as we do it on localhost. Make media files available only for authenticated users requires only few lines of code:
from django.conf.urls import patterns, include, url
from django.contrib.auth.decorators import login_required
from django.views.static import serve
from django.conf import settings
@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'^%s(?P<path>.*)$' % settings.MEDIA_URL[1:], protected_serve, {'document_root': settings.MEDIA_ROOT}),
)
This solution is fast and nice, but doesn't have to be sufficient if we have to serve large files or if we expect high traffic.
2) Unpredictable urls
Second option is to let web server to serve media files but save files on unpredictable urls, e.g.:
/media/z45fhjkfd456/gjke345dsdf3/file.jpg
Complexity of problem of finding the path is similiar to the complexity of finding credentials. From this perspective this approach isn't vulnerable.
Weakness of this approach is that users can provide this URL to third parties (consciously as well as unconsciously).
Also don't forget to prevent search engines from indexing your media by adding this line to your robots.txt (thanks x0nix for this comment).
Disallow: /media/*
3) X-Sendfile
This solution is probably the most difficult to implement as it requires cooperation of django and web server. However it provides both important aspects - security and high performance. You can read quite nice summary about what is x-sendfile. There is also django wrapper. However, I have to admit I didn't try this solution yet.