Restricting file access to users who uploaded the file.

164 views
Skip to first unread message

Gaurav Gupta

unread,
Oct 21, 2014, 7:14:17 AM10/21/14
to django...@googlegroups.com
What is the best way to restrict access of files to specific users. I want to give read access to the user who uploaded the files. 
In the normal django implementation there seems to be no way to restrict access to file uploads in MEDIA_ROOT. What's the best way to achieve this? Ideally I would also like to send files to S3 and restrict access in the cloud as well. 

Thanks for your help.

Ben Lopatin

unread,
Oct 21, 2014, 10:09:50 AM10/21/14
to django...@googlegroups.com
What you want to do is first restrict access to the model instance to which the file is associated. Presumably this model has a foreign key to your User model which you'd associate with the uploading user. Then your view will return some non-200 response, like a 401 response if the requesting user doesn't match the associated user.

Your view for accessing the file could return the file itself (not ideal), redirect to the actual file name (security by obscurity), or act as a guard for the file server (let's do that). Presuming you're working with Nginx or Apache and local files, you can use X-Accel-Redirects or X-Sendfile to do this. Basically the request for a file is made to your Django app, e.g. /files/some-file-name.doc, and the app checks if the user can access it. If so, the app returns the request with a new header (x-accel-redirect) and the file path - this isn't immediately sent to the client, but is instead resolved by the web server (i.e. Nginx or Apache) by returning the file from its location on the file system. Django verifies, Nginx/Apache does the file serving (full explanation here: http://wellfireinteractive.com/blog/nginx-django-x-accel-redirects/).

You can follow a similar strategy for private S3 files, but instead of serving them from the web server, generate a temporary access URL to the S3 resource and return that to the client (http://www.gyford.com/phil/writing/2012/09/26/django-s3-temporary.php).

Jon Dufresne

unread,
Oct 21, 2014, 12:00:51 PM10/21/14
to django...@googlegroups.com
On Tue, Oct 21, 2014 at 7:09 AM, Ben Lopatin <b...@wellfire.co> wrote:
> Presuming you're working with Nginx or
> Apache and local files, you can use X-Accel-Redirects or X-Sendfile to do
> this. Basically the request for a file is made to your Django app, e.g.
> /files/some-file-name.doc, and the app checks if the user can access it. If
> so, the app returns the request with a new header (x-accel-redirect) and the
> file path - this isn't immediately sent to the client, but is instead
> resolved by the web server (i.e. Nginx or Apache) by returning the file from
> its location on the file system. Django verifies, Nginx/Apache does the file
> serving (full explanation here:
> http://wellfireinteractive.com/blog/nginx-django-x-accel-redirects/).

If you're looking for a nice Django app that does this bit for you
with a simple API, check out Django Sendfile
<https://github.com/johnsensible/django-sendfile>. However, you'll
still need to configure the web server end.

Cheers,
Jon
Reply all
Reply to author
Forward
0 new messages