Как заставить использование SSL для некоторых URL моего приложения Django? - PullRequest
11 голосов
/ 10 октября 2009

Я хочу быть уверен, что для некоторых URL моего сайта будет использоваться SSL. Я видел много ответов уже на SO.

Принудительное перенаправление на SSL для всех страниц, кроме одного

Так что я думаю, что буду использовать mod_rewrite.

Мой вопрос больше о том, как настроить виртуальный хост для запуска моего приложения Django через HTTP и HTTPS без проблем. Я использую WSGI.

Является ли проблемой просто дублировать конфигурацию через *:443 и *:80? Что я должен сделать, чтобы иметь лучшую конфигурацию?

Ответы [ 4 ]

11 голосов
/ 11 октября 2009

Если под WSGI вы на самом деле имеете в виду Apache / mod_wsgi, то, хотя смонтированные приложения WSGI обычно запускаются в своих собственных подчиненных интерпретаторах, разделение 80/443 является особым случаем и даже в другом VirtualHost, если точка монтирования для WSGIScriptAlias, и имя сервера совпадают, они будут объединены.

<VirtualHost *:80>
ServerName www.example.com

WSGIScriptAlias / /some/path/django.wsgi.
</VirtualHost>

<VirtualHost *:443>
ServerName www.example.com

WSGIScriptAlias / /some/path/django.wsgi.
</VirtualHost>

Это будет происходить и в режиме демона, но в режиме демона вам нужно определить только одну группу процессов демона в первом определении VirtualHost, а затем просто сослаться на это из обоих с помощью WSGIProcessGroup.

<VirtualHost *:80>
ServerName www.example.com

WSGIDaemonProcess mydjangosite ...
WSGIProcessGroup mydjangosite

WSGIScriptAlias / /some/path/django.wsgi.
</VirtualHost>

<VirtualHost *:444>
ServerName www.example.com

WSGIProcessGroup mydjangosite

WSGIScriptAlias / /some/path/django.wsgi.
</VirtualHost>

WSGIProcessGroup может работать как с VirtualHost только для одного и того же ServerName.

Django предоставляет метод is_secure () для определения, когда запрос поступил через HTTPS, который происходит от переменной WSGI с запросом wsgi.url_scheme, который устанавливается mod_wsgi.

Итак, у вас будет один файл скрипта Django WSGI и файл настроек. Вам просто нужно продублировать монтирование приложения, как описано в конфигурации Apache / mod_wsgi.

10 голосов
/ 11 октября 2009

Помимо использования mod_rewrite, вы также можете использовать Django для управления перенаправлениями SSL.

Вот модифицированная версия промежуточного программного обеспечения из Satchmo Project . Мне больше нравится этот метод, чем mod_rewrite, так как им легче управлять.

Чтобы использовать его, передайте 'SSL': True в ваш URL-адрес:


    urlpatterns = patterns('some_site.some_app.views',
        (r'^test/secure/$','test_secure',{'SSL':True}),
    )

Вот код промежуточного программного обеспечения:


    from django.conf import settings
    from django.http import HttpResponseRedirect, get_host

    SSL = 'SSL'

    def request_is_secure(request):
        if request.is_secure():
            return True

        # Handle forwarded SSL (used at Webfaction)
        if 'HTTP_X_FORWARDED_SSL' in request.META:
            return request.META['HTTP_X_FORWARDED_SSL'] == 'on'

        if 'HTTP_X_SSL_REQUEST' in request.META:
            return request.META['HTTP_X_SSL_REQUEST'] == '1'

        return False

    class SSLRedirect:
        def process_request(self, request):
            if request_is_secure(request):
                request.IS_SECURE=True
            return None

        def process_view(self, request, view_func, view_args, view_kwargs):          
            if SSL in view_kwargs:
                secure = view_kwargs[SSL]
                del view_kwargs[SSL]
            else:
                secure = False

            if settings.DEBUG:
                return None

            if getattr(settings, "TESTMODE", False):
                return None

            if not secure == request_is_secure(request):
                return self._redirect(request, secure)

        def _redirect(self, request, secure):
            if settings.DEBUG and request.method == 'POST':
                raise RuntimeError(
                """Django can't perform a SSL redirect while maintaining POST data.
                    Please structure your views so that redirects only occur during GETs.""")

            protocol = secure and "https" or "http"

            newurl = "%s://%s%s" % (protocol,get_host(request),request.get_full_path())

            return HttpResponseRedirect(newurl)

3 голосов
/ 04 февраля 2014

Вот декоратор представления, который вы можете применить к представлениям, которые должны иметь HTTPS.

from functools import wraps
from django.conf import settings
from django.http import HttpResponseRedirect


def require_https(view):
    """A view decorator that redirects to HTTPS if this view is requested
    over HTTP. Allows HTTP when DEBUG is on and during unit tests.

    """

    @wraps(view)
    def view_or_redirect(request, *args, **kwargs):
        if not request.is_secure():
            # Just load the view on a devserver or in the testing environment.
            if settings.DEBUG or request.META['SERVER_NAME'] == "testserver":
                return view(request, *args, **kwargs)

            else:
                # Redirect to HTTPS.
                request_url = request.build_absolute_uri(request.get_full_path())
                secure_url = request_url.replace('http://', 'https://')
                return HttpResponseRedirect(secure_url)

        else:
            # It's HTTPS, so load the view.
            return view(request, *args, **kwargs)

    return view_or_redirect
0 голосов
/ 11 октября 2009

Мы использовали простое промежуточное программное обеспечение для проверки URL-адресов по списку базовых URL-адресов, которые должны находиться в режиме HTTPS, все остальные переводятся в режим HTTP. Большое предостережение заключается в том, что любые данные POST могут быть потеряны, если вы не проявите особую осторожность (в нашем случае это не имело значения). Мы делали это на страницах присоединения, для которых требовались номера кредитных карт и тому подобное, поэтому, как только они были в этом конвейере, мы принудительно вводили их в HTTPS.

...