Django应用程序在apache中的设置,某些页面需要ssl

settings in apache for django app which need ssl for some pages

我的django应用程序(我叫它partlysecureapp)有一个对所有人可见的索引页面。所有其他页面(可从索引页面上的链接访问)都需要用户登录。我想使用该应用程序apache2中具有SSL的服务器。

我已经在使用SSL的apache上部署了一个应用程序(例如mysecureapp),该应用程序包含所有需要用户登录的页面。我为此进行了如下配置。

我的apache2位于/etc/apache2,它具有以下目录结构。

1
2
3
4
5
6
7
8
9
10
11
/etc/apache2/
            |--conf.d---*charset,security,localized-error-pages*
            |---mods-available---...
            |---mods-enabled---...
            |---sites-available---default,default-ssl,ssl
            |---sites-enabled---shortcut to ssl
            |---apach2.conf
            |---httpd.conf
            |---ports.conf
            |---magic
            |---envvars

对于secureapp,我已经在文件sites-available/ssl

中进行了设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<VirtualHost *:443>
    ServerAdmin webmaster@localhost

    DocumentRoot /home/dev/python/django/mysecureapp

        SSLEngine on
        SSLOptions +StrictRequire
        SSLCertificateFile /etc/ssl/certs/server.crt
        SSLCertificateKeyFile /etc/ssl/private/server.key
    ...
    WSGIScriptAlias /mysecureapp /home/dev/python/django/mysecureapp/mysecureapp.wsgi
    Alias /site_media/ /home/dev/python/django/mysecureapp/media/

</VirtualHost>

这很好用..

要部署我的partlysecureapp

http://127.0.0.1:8080/partlysecureapp/需要显示所有人都可以访问的索引页面。
但是

1
2
3
../partlysecureapp/link1/
../partlysecureapp/link2/
../partlysecureapp/link3/

需要登录,应通过ssl提供服务。

我认为,我需要为partlysecureapp添加另一个WSGIScriptAlias。我是否需要为partlysecureapp添加另一个DocumentRoot?如何告诉apache通过ssl端口从端口8080和其他服务器提供索引页?

到目前为止,/etc/apache2/httpd.conf为空白。仅sites-available/ssl文件具有VirtualHost元素。


首先,让我们在这里分开关注点:一件事是要求登录,另一件事是要求SSL。前者特定于Django,应在您的视图中进行处理;对于后者,恕我直言,您应该考虑通过SSL提供所有内容的可能性,这将大大简化您的设置。当然,会有一些开销,这取决于您决定对您的特定情况是否重要。

也就是说,对于您提出的方案:

  • 要通过纯HTTP提供任何服务,您需要监听端口80(或者您的情况下为8080)。因此,您需要一个绑定到该端口的单独的VirtualHost,并为其自身使用单独的WSGI应用程序。

  • 要允许来自此虚拟主机的单个路径(您的索引文件),但要求其他所有内容都受SSL保护,请使用mod_rewrite

    1
    2
    3
    RewriteEngine On
    RewriteRule ^/partlysecureapp$ - [L,NC]
    RewriteRule (.*) https://127.0.0.1/partlysecureapp%{REQUEST_URI} [L,R=301]

    第一个规则告诉Apache如果该路径与您的根路径完全一样,则不要执行任何重定向;第二个将其他所有内容重定向到https(将由您的*:443虚拟主机处理)。

    (注意:您可能还希望在没有SSL的情况下投放/site_media)

  • 然后,您只需添加WSGI别名即可;即使Django将用户发送到其他页面,Apache也将确保通过SSL为该页面提供服务。

  • 您的最终代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <VirtualHost *:8080>
        ServerAdmin webmaster@localhost

        DocumentRoot /home/dev/python/django/partlysecureapp

        RewriteEngine On
        RewriteRule ^/partlysecureapp$ - [L,NC]
        RewriteRule ^/site_media - [L,NC]
        RewriteRule (.*) https://127.0.0.1/partlysecureapp%{REQUEST_URI} [L,R=301]

        ...
        WSGIScriptAlias /partlysecureapp /home/dev/python/django/partlysecureapp/partlysecureapp.wsgi
        Alias /site_media/ /home/dev/python/django/partlysecureapp/media/
    </VirtualHost>

    并且您受SSL保护的虚拟主机的代码与mysecureapp相同(当然,使用partlysecureapp;请注意,您可以使两个应用程序并行运行,请注意您的MEDIASTATIC路径)。