私の元々の質問は、 Djangoログインページ)のHTTPSを有効にする で、唯一の応答で、私は-サイト全体を作成することをお勧めしましたHTTPSのみとして。
Django 1.3とnginxを使用している場合、サイトをHTTPS専用にする正しい方法は何ですか?
1つの応答で ミドルウェアソリューション が言及されましたが、警告がありました。
Djangoは、POSTデータを保持している間、SSLリダイレクトを実行できません。リダイレクトがGET中にのみ発生するようにビューを構成してください。
nginxによるhttpsへの書き換え についてのサーバーフォールトに関する質問、データを失うPOSTの問題についても言及しました。
EFFによるHTTPSのみへの推奨 、次のことに注意してください。
アプリケーションは、設定時にCookieにSecure属性を設定する必要があります。この属性は、安全な(HTTPS)トランスポートを介してのみCookieを送信し、決して安全ではない(HTTP)ようにブラウザに送信するように指示します。
Django-authのようなアプリには、Cookieをセキュアとして設定する機能がありますか?または、さらにミドルウェアを作成する必要がありますか?
したがって、Django/nginxの組み合わせを設定してHTTPSのみを実装する最良の方法は次の点です。
Edit-複数のブラウザのテスト中に発見した別の問題。検索フォーム/ボタンがあるURL https://mysite.com/search/
があるとします。ボタンをクリックして、フォームをDjango=通常どおりに処理し、Django HttpResponseRedirect to http://mysite.com/search?results="foo"
。]を実行します。 Nginxは、必要に応じてhttps://mysite.com/search?results="foo"
にリダイレクトします。
しかし--Operaはリダイレクトが発生したときに可視flashを持ちます。同じ検索語であってもすべての検索が発生します(本当にhttpsキャッシュしない:)さらに悪いことに、IEでテストすると、最初にメッセージが表示されます。
安全でない接続にリダイレクトされようとしています-続行しますか?
[はい]をクリックすると、すぐに次のようになります。
安全な接続でページを表示しようとしています-続行しますか?
2番目のIE警告にはそれをオフにするオプションがあります-first警告にはないため、誰かが検索してリダイレクトされるたびに結果ページには、少なくとも1つの警告メッセージが表示されます。
ジョンCの答えの2番目の部分、およびDjango 1.4 + ...
HttpResponseRedirectを拡張する代わりに、_request.scheme
_をhttps
に変更できます。 DjangoはNginxのリバースプロキシの背後にあるため、元のリクエストが安全だったことはわかりません。
Django設定で、 SECURE_PROXY_SSL_HEADER 設定を設定します。
_SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
_
次に、Nginxがリバースプロキシでカスタムヘッダーを設定する必要があります。 Nginxサイトの設定:
_location / {
# ...
proxy_set_header X-Forwarded-Proto $scheme;
}
_
このように_request.scheme == 'https'
_およびrequest.is_secure()
はTrueを返します。 request.build_absolute_uri()
は_https://...
_などを返します...
ここに私がこれまでに解決した解決策があります。 nginxの構成とDjangoのコードの記述の2つの部分があります。 nginx部分はexternalリクエストを処理し、http
ページをhttps
にリダイレクトし、Django=コードハンドルinternalhttp
プレフィックスを持つURL生成(少なくとも、HttpResponseRedirect()
から生じるもの)。組み合わせて、うまく機能するようです-私が知る限り、クライアントブラウザーはユーザーが自分で入力しなかったhttp
ページを見ることはありません。
_# nginx.conf
# Redirects any requests on port 80 (http) to https:
server {
listen 80;
server_name www.mysite.com mysite.com;
rewrite ^ https://mysite.com$request_uri? permanent;
# rewrite ^ https://mysite.com$uri permanent; # also works
}
# Django pass-thru via uWSGI, only from https requests:
server {
listen 443;
ssl on;
ssl_certificate /etc/ssl/certs/mysite.com.chain.crt;
ssl_certificate_key /etc/ssl/private/mysite.com.key;
server_name mysite.com;
location / {
uwsgi_pass 127.0.0.1:8088;
include uwsgi_params;
}
}
_
SERVER_TYPE = "DEV"
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True#現在DjangoのDevブランチのみ。
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
_# mysite.utilities.decorators.py
import settings
def HTTPS_Response(request, URL):
if settings.SERVER_TYPE == "DEV":
new_URL = URL
else:
absolute_URL = request.build_absolute_uri(URL)
new_URL = "https%s" % absolute_URL[4:]
return HttpResponseRedirect(new_URL)
# views.py
def show_items(request):
if request.method == 'POST':
newURL = handle_post(request)
return HTTPS_Response(request, newURL) # replaces HttpResponseRedirect()
else: # request.method == 'GET'
theForm = handle_get(request)
csrfContext = RequestContext(request, {'theForm': theForm,})
return render_to_response('item-search.html', csrfContext)
def handle_post(request):
URL = reverse('item-found') # name of view in urls.py
item = request.REQUEST.get('item')
full_URL = '%s?item=%s' % (URL, item)
return full_URL
_
HTTPS_Response()
をdecoratorとして書き換えることができることに注意してください。利点は、すべてのコードを調べてHttpResponseRedirect()
を置き換える必要がないことです。欠点-HttpResponseRedirect()
の前にデコレーターを配置する必要があります。これはDjango at _Django.http.__init__.py
_。)です。Djangoのコードが、それはあなた次第です-それは確かに1つのオプションです。
サイト全体をhttpsの後ろに置いておくと、Djangoの終わりで心配する必要はありません(nginxとDjangoの間でのみデータを保護する必要がないと仮定しますユーザーとサーバー)