私のウェブサイトの一部のURLには、SSLが使用されることを確認したいと思います。私はすでにSOで多くの答えを見ました。
だから私は使うと思いますmod_rewrite
。
私の質問は、 Djangoアプリケーションを問題なく何度も実行するように仮想ホストを構成する方法についてです。私はを使用しています。HTTP
HTTPS
WSGI
*:443
設定を何度も複製するのは問題*:80
ですか?最適な構成にするにはどうすればよいですか?
私のウェブサイトの一部のURLには、SSLが使用されることを確認したいと思います。私はすでにSOで多くの答えを見ました。
だから私は使うと思いますmod_rewrite
。
私の質問は、 Djangoアプリケーションを問題なく何度も実行するように仮想ホストを構成する方法についてです。私はを使用しています。HTTP
HTTPS
WSGI
*:443
設定を何度も複製するのは問題*:80
ですか?最適な構成にするにはどうすればよいですか?
WSGI が実際に Apache/mod_wsgi を意味する場合、マウントされた WSGI アプリケーションは通常、独自のサブ インタープリターで実行されますが、80/443 分割は特殊なケースであり、たとえ WSGIScriptAlias のマウント ポイントと ServerNameが同じ場合、それらはマージされます。
<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 は、同じ ServerName の VirtualHost にのみ到達できます。
Django は、mod_wsgi によって設定される 'wsgi.url_scheme' と呼ばれる要求を持つ WSGI 変数から派生する HTTPS 経由で要求がいつ来たかを判断するための is_secure() メソッドを提供します。
したがって、Django WSGI スクリプト ファイルと設定ファイルは 1 つだけになります。Apache/mod_wsgi 構成で説明されているように、アプリケーションのマウントを複製するだけです。
mod_rewrite を使用する以外に、Django を使用して SSL リダイレクトを制御することもできます。
これは、 Satchmo Projectのミドルウェアの修正版です。管理が簡単なため、mod_rewrite よりもこの方法を好む傾向があります。
これを使用するには、'SSL':True を URL conf に渡します。
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)
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
簡単なミドルウェアを使用して、HTTPS モードである必要があるベース URL のリストに対して URL をチェックし、その他はすべて HTTP モードに強制されます。ここでの大きな注意点は、特に注意しないと POST データが失われる可能性があることです (この場合は問題ありませんでした)。クレジットカード番号などを必要とする参加ページでこれを行っていたので、それらがパイプラインに入るとすぐに HTTPS に強制しました。