Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restricting access to static files in Django/Nginx

I am building a system that allows users to generate a documents and then download them. The documents are PDFs (not that it matters for the sake of this question) and when they are generated I store them on my local file system that the web server is running on with uuid file names

c7d43358-7532-4812-b828-b10b26694f0f.pdf

but I know "security through obscurity" is not the right solution ...

I want to restrict access to they files on a per account basis if possible. One thing I think I could do is upload them to S3 and provide a signed URL, but I want to avoid that for now if possible.

I am using Nginx/Django/Gunicorn/EC2/S3

What are some other solutions?

like image 387
josephmisiti Avatar asked Mar 21 '12 18:03

josephmisiti


2 Answers

If you are serving small files, you can indeed use Django to serve them directly, writing the file into the HttpResponse object.

If you're serving large files however, you might want to leave that task to your webserver, you can use the X-Accel-Redirect header on Nginx (and X-Sendfile for Apache & Lighttpd) to have your webserver serve the file for you.

You can find more information about the header itself in Nginx's documentation here, and you could find some inspiration as to how to use that in Django here.

Once you're done sending files through Django views, enforcing user authentication should be pretty straightfoward using Django's auth framework.

like image 149
Thomas Orozco Avatar answered Sep 20 '22 17:09

Thomas Orozco


How about enforcing user==owner at the view level, preventing access to the files, storing them as FileFields, and only retrieving the file if that condition is met.

e.g. You could use the @login_required decorator on the view to allow access only if logged in. This could be refined using request.user to check against the owner of the file. The User Auth section of the Django documentation is likely to be helpful here.

The other option, as you mention is via S3 itself, generating urls within Django which have a querystring allowing an authenticated user access to download a particular s3 object with a time limit. Details on that can be found at the s3 documentation. A similar question has been asked before here on SO.

like image 22
jvc26 Avatar answered Sep 17 '22 17:09

jvc26