Pinax& Apache:仅向经过身份验证的用户提供附件

时间:2009-11-26 00:24:10

标签: django apache pinax

我希望Apache和Pinax仅向经过身份验证的用户提供附件。

我发现了这个post,但我无法使其发挥作用。

我的Apache-conf文件:

WSGIPythonPath /usr/local/bin/python

<VirtualHost *:80>
    ServerName      www.domain.com
    ServerAlias     domain.com


    WSGIDaemonProcess k-production python-path=/path/to/app/pinax-env/lib/python2.6/site-packages
    WSGIProcessGroup k-production

    Alias /site_media  /path/to/app/cp/site_media    
    <Directory /path/to/app/cp/site_media>
    Order deny,allow
    Allow from all
    </Directory>

    WSGIScriptAlias /site_media/media/attachments /path/to/app/cp/deploy/pinax.wsgi
    <Directory /path/to/app/cp/site_media/media/attachments>
    Deny from all
    </Directory>

    XSendFile On
    XSendFileAllowAbove On

    WSGIScriptAlias / /path/to/app/cp/deploy/pinax.wsgi
    <Directory /path/to/app/cp/deploy>
        Order deny,allow
        Allow from all
    </Directory>

</VirtualHost>

和我的(仍然粗糙)视图,应该被调用:

@login_required 
def sendfile(request, slug): 

    app, content_object_id, img = slug.split('/')
    project_file = get_object_or_404(Attachment, attachment_file = 'attachments/'+slug) 
    response = HttpResponse() 
    response['X-Sendfile'] =  os.path.join(settings.MEDIA_ROOT,   'attachments/'+slug) 
    content_type = 'application/octet-stream' 
    response['Content-Type'] = content_type 
    response['Content-Disposition'] = 'attachment; filename="%s"' %  os.path.basename(os.path.join(settings.MEDIA_ROOT,   'attachments/'+slug))
    return response 

无论用户是否登录,Apache都会抛出403.

通过开发服务器,我可以访问视图,但不会传输任何数据。

有什么问题?

2 个答案:

答案 0 :(得分:1)

我试图完全做同样的事情,解决方案结果是没有使用WSGIScriptAlias,而是使用常规Alias来定义一个wsgi处理程序的目录。对于视图,我基本上只是在django.views.static.serve。

周围写了一个包装器

我的apache conf最终看起来像这样:

# myproject
<VirtualHost *:8080>
    #DocumentRoot /var/www/myproject/public
    ServerName myproject
    ErrorLog /var/www/myproject/logs/apache_error_log
    CustomLog /var/www/myproject/logs/apache_access_log common

    AliasMatch ^/(media/uploads/protected/.*) /var/www/myproject/src/myproject-trunk/server/django.wsgi/$1
    Alias /media/ /var/www/myproject/public/media/
    Alias / /var/www/myproject/src/myproject-trunk/server/django.wsgi/

    <Directory /var/www/myproject/src/myproject-trunk/server>
        Options ExecCGI
        AddHandler wsgi-script .wsgi
        # WSGIApplicationGroup %{GLOBAL}
        Order allow,deny
        Allow from all
    </Directory>

    <Directory /var/www/myproject/public/media>
        Order deny,allow
        Allow from all
    </Directory>
</VirtualHost>

答案 1 :(得分:1)

首先尝试专注于开发服务器 - 因为它设置更简单,因此更不容易出错。

也许试试这个:

@login_required  def sendfile(request, slug): 
    ## these are never used    
    # app, content_object_id, img = slug.split('/')
    # project_file = get_object_or_404(Attachment, attachment_file = 'attachments/'+slug)

    response = HttpResponse() 
    response['X-Sendfile'] =  os.path.join(settings.MEDIA_ROOT,   'attachments/'+slug)

    import pdb; pdb.set_trace() 
    # your development server will stop here
    # you can now inspect the your context, e.g.
    # >> p response['X-Sendfile']
    # this should print the value of response['X-Sendfile']
    # >> c
    # this will continue program execution
    # for more commands see http://www.python.org/doc/2.4/lib/debugger-commands.html

    content_type = 'application/octet-stream' 
    response['Content-Type'] = content_type 
    # Content-Disposition filename is only for suggesting a name for the file
    # when the user tries to download it, e.g.:
    # response['Content-Disposition'] = 'attachment; filename='localfile.txt'
    response['Content-Disposition'] = 'attachment; filename="%s"' %  os.path.basename(os.path.join(settings.MEDIA_ROOT, 'attachments/'+slug))
    return response

但是通过使用开发服务器,您将无法获得任何文件,因为Apache将执行文件服务。 您可以确保,发送到Apache的数据是正确的。 或使用(不推荐用于您的生产服务器)

f = open(os.path.join(settings.MEDIA_ROOT, 'attachments/'+slug), 'rb')
response = HttpResponse(f.read())

而不是

response = HttpResponse() 
response['X-Sendfile'] =  os.path.join(settings.MEDIA_ROOT, 'attachments/'+slug)

部分链接: