3

From my Django application I want to serve up secure photos. The photos are not for public consumption, I only want logged in users to have the ability to view them. I don't want to rely on obfuscated file id's (giving a photo a UUID of a long number) and count on that being hidden in my media folder. How would I store a photo securely on disk in my database and only stream it out to an authenticated session?

MikeN
  • 45,039
  • 49
  • 151
  • 227

3 Answers3

6

Use X-Sendfile headers to tell your front end server what file to actually server.

@check_permissions
def image(request):
    response = HttpResponse(mimetype='image/png')    
    response['X-Sendfile'] = "/real/path/to/image.png"
    return response

Here is a related question. You can also see a real world implementation by looking at how Satchmo serves DownloadableProduct objects.

One final note, nginx and lighttpd use X-Accel-Redirect and X-LIGHTTPD-send-file instead of X-Sendfile.

Community
  • 1
  • 1
istruble
  • 13,363
  • 2
  • 47
  • 52
  • That does not seem to work with the built-in server. Is that correct or am I doing something wrong? – Debilski May 04 '10 at 15:55
  • No, I guess built-in server would not support such, but then again, it's not supposed to be used in production anyway. Maybe have it as an setting if devel-server is needed. – odinho - Velmont Dec 31 '10 at 12:46
  • Correct, the X-Sendfile header stuff is basically an internal redirect being sent from a heavy weight backend server to a light weight front-end server. – istruble Jan 03 '11 at 07:31
2

You can do this by creating a HttpResponse with the mime type of the image and then writes/copies the image file to it.

A simple version could look like the following:

from django.http import HttpResponse

@your_favourite_permission_decorator
def image(request):
    response = HttpResponse(mimetype='image/png')

    with open("image.png") as img:
        response.write(img.read())
    return response

Also, see this example for PDF files and this example with PIL.

Debilski
  • 66,976
  • 12
  • 110
  • 133
0

If it was Apache server with mod_python, this could potentially be an interesting article about Apache using Django's authentication system.

Damian
  • 449
  • 4
  • 11