2. セキュアリクエストでしかアクセスできないように制限をかける¶
2.1. URLでアクセスを制限する¶
セキュアURLにアクセスを制限する方法の一つは、URLでアクセスを制限することです。 こと方法で、一部のURLでアクセスを制限することができます。
例えば、ユーザーアカウント関連ページを全部 HTTPS で制限したい場合は、 /accounts/ で始まるURLを制限することができます。同じく、購入や、決済 の /payment/ で始まるURLを制限することができます。
2.1.1. SSLRedirectMiddleware を利用¶
- class beproud.django.ssl.middleware.SSLRedirectMiddleware¶
SSLRedirectMiddleware を利用すれば、全サイトにセキュアリクエストの制限をかけることができます。
SSLRedirectMiddleware で SSL_URLS という設定を利用し、 ある URL は SSL でアクセスするかどうかが決まります。 SSL_URLS を settings.py に設定します。 SSL_URLS は request.path_info で定義されている URL にマッチする正規表現のリストになります。 いずれかの正規表現がと マッチした場合、その URL はセキュアURLとして処理します。 例えば、以下の設定によって、 http://www.example.com/login/ という URL でアクセスが来た場合、 SSL_URLS の正規表現にマッチしたため、 ユーザーは https://www.example.com/login/ にリダイレクトされます。正規表現にマッチする URL は urls.py と違って、 ‘/’ 文字から始まりますので、ご注意ください。
SSL_URLS = (
'^/login/',
'^/purchase/'
# ...
)
HTTP でも、 HTTPSでも、アクセスできるようにしたい場合は、 SSL_IGNORE_URLS に設定できます。例えば、 静的ファイルや、国際化 javascript は HTTP でも、HTTPSでも、 アクセスする必要がある場合が多い。 SSL_IGNORE_URLS の書き方は SSL_URLS の書き方と一緒です。
SSL_IGNORE_URLS = (
'^/i18n_js$',
'^/static/',
# ...
)
SSLRedirectMiddleware は以下のように作動します:
- リクエストURLが SSL_IGNORE_URLS にマッチした場合、 何もしないで、処理が終わる。
- リクエスト URL が SSL_URLS にマッチし、リクエストが HTTP で来ている場合、HTTPS URLにリダイレクトする。
- リクエスト URL が SSL_URLS にマッチしないで、 リクエストが HTTPS で来ている場合、HTTP URLにリダイレクトする。
ノート
HTTPS で HTTP ページにアクセスすると、セキュリティが普段より高くて、 問題が無いのですが、セキュアでないページに HTTPS でアクセスすると、 HTTP 用のページにリダイレクトするのは、複数のページに同じコンテンツが 出来てしまい、検索エンジンの混乱、 REST のルールを破ることを 避けるための操作です。
2.2. ビューでアクセスを制限する¶
ビューでセキュアアクセス制限をかける場合もあります。複数のURLで同じビューで アクセスする場合もあり、ある機能へのアクセスを制限したい場合があります。 その場合、URLでアクセス制限をかけるのに合わないでしょう。
2.2.1. 生真面目なやり方¶
複数のURLで同じビューへアクセスする場合があるので、ビューでセキュアアクセス制限 に対応すると以下のようになります。生真面目なやり方は、ビューの中に request.is_secure() でリクエストがセキュアかどうかをチェックします:
from django.http import HttpResponseRedirect
from django.http import get_host
def my_secure_view(request):
if request.is_secure():
return HttpResponseRedirect("https://%s%s" % (get_host(request), request.get_full_path()))
# ...
しかし、このやり方でやりますと、 SSLRedirectMiddleware はこのビューがセキュアかどうかがわかる用がなく、URLを SSL_IGNORE_URLS に追加しないと、 当ビューの処理と眩みます。
2.2.2. ssl_view デコレーター¶
- beproud.django.ssl.decorators.ssl_view()¶
ショートカットとして、あるビューはセキュアビューであることを指定するために ssl_view() を使うことができます:
from beproud.django.ssl.decorators import ssl_view
@ssl_view
def my_secure_view(request):
...
ssl_view() は SSLRedirectMiddleware と同じ処理を実装しますが、 SSL_URLS にURLを設定するのが不要に なります。このビューがセキュアということが指定されているので、 SSLRedirectMiddleware と眩みません。
2.3. HTTP リバースプロクシを利用する¶
- class beproud.django.ssl.middleware.SSLProxyMiddleware¶
SSLProxyMiddleware はプロクシサーバーからセキュアリクエストが来た場合、 request.is_secure() が True を返すようにリクエストオブジェクトを更新する。 SSLProxyMiddleware と 連動するためにリバースプロクシを設定すう方法は ウェブサーバー設定 にご参照ください。
あるリクエストがセキュアかどうかを指定するヘッダーの名前とセキュアの場合の値を SSL_REQUEST_HEADER で設定する必要があります。 デフォールトの値は以下に示します。
SSL_REQUEST_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')
SSLProxyMiddleware は以下の ように作動します:
- SSL_REQUEST_HEADER で設定されているヘッダーの 値がリバースプロクシから送られて来たリクエストヘッダーと一致すると、 request.is_secure() が正値を返すように設定します。
ノート
request.is_secure() を使うミドルウエアがある可能性があるため、 SSLProxyMiddleware を なるべく上のほうに MIDDLEWARE_CLASSES に設定すべきです。 少なくとも、 SSLRedirectMiddleware. の上に設定する必要があります。