Django Nginx X-Accel-Redirect for protected files

2019-05-31 23:25发布

If you want to torment someone until the end of time, just get them to configure Django and Nginx X-Accel-Redirect. This is literally impossible, I have been trying for days.

I am trying to only allow certain files to be downloaded from logged in views in django using Nginx on webfaction. Here is what I have:

Custom Nginx app listening on port 27796 under /static. Here is the conf.

http {
include       mime.types;
default_type  application/octet-stream;
sendfile        on;
keepalive_timeout  65;
server {
    listen       27796;
    server_name  myurl.com;
    root /home/ucwsri/webapps/static_media_ucwsri_nginx; 

    location / {
        autoindex on;
    }

    location ^.*/protected-files {
        internal;
        alias /home/ucwsri/webapps/static_media_ucwsri_nginx/protected;
    }

All static content is in /home/ucwsri/webapps/static_media_ucwsri_nginx, and is being correctly served by this Nginx app.

The files I want protected are here:

/home/ucwsri/webapps/static_media_ucwsri_nginx/protected

Which is the alias listed under the location ^.*/protected-files block in Nginx.

The view simply makes an Http Response thus:

response = HttpResponse()
url = "/static/protected-files/some-file.pdf"
response['X-Accel-Redirect'] = url

return response

Where the 'some-file.pdf' file exists in

/home/ucwsri/webapps/static_media_ucwsri_nginx/protected

Whatever I try I get a 404 from Nginx when trying to get that file as a POST request that goes to that view. I have tried everything I can think of, every location combination block, nothing works. Always a 404.

Someone please put me out of my misery and tell me what I have done wrong. This is truly brutal for something seemingly so simple.

1条回答
Deceive 欺骗
2楼-- · 2019-05-31 23:59

First, your location ^.*/protected-files is nonsense. I guess, you've missed ~ modifier, but even in that case it would be useless.

Second, you have not protected /protected/ folder. Direct request to /protected/some-file.pdf will download that file without any protection.

Third, you have /static/protected-files/some-file.pdf in X-Accel-Redirect, but you didn't mention any static folder before.

So, I would suggest following config:

server {
    listen       27796;
    server_name  myurl.com;
    root /home/ucwsri/webapps/static_media_ucwsri_nginx; 

    location / {
        autoindex on;
    }

    location ^~ /protected/ {
        internal;
    }

And django should be:

response = HttpResponse()
url = "/protected/some-file.pdf"
response['X-Accel-Redirect'] = url

return response

Summary:

  • Protect real folder.
  • X-Accel-Redirect is URI, just think about it as if user put that URI in browser address bar. The only difference is that internal will allow access with X-Accel-Redirect while forbid direct user access from browser.
查看更多
登录 后发表回答