APIコントローラーにSSLを使用させたいので、別のlistenディレクティブをnginx.confに追加しました
upstream Unicorn {
server unix:/tmp/Unicorn.foo.sock fail_timeout=0;
}
server {
listen 80 default deferred;
listen 443 ssl default;
ssl_certificate /etc/ssl/certs/foo.crt;
ssl_certificate_key /etc/ssl/private/foo.key;
server_name foo;
root /var/apps/foo/current/public;
try_files $uri/system/maintenance.html $uri/index.html $uri @Unicorn;
location @Unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_Host;
proxy_redirect off;
proxy_pass http://Unicorn;
}
error_page 502 503 /maintenance.html;
error_page 500 504 /500.html;
keepalive_timeout 5;
}
これは、nginx conftestに問題なく合格します。また、ApiControllerにforce_ssl
ディレクティブを追加しました
class ApiController < ApplicationController
force_ssl if Rails.env.production?
def auth
user = User.authenticate(params[:username], params[:password])
respond_to do |format|
format.json do
if user
user.generate_api_key! unless user.api_key.present?
render json: { key: user.api_key }
else
render json: { error: 401 }, status: 401
end
end
end
end
def check
user = User.find_by_api_key(params[:api_key])
respond_to do |format|
format.json do
if user
render json: { status: 'ok' }
else
render json: { status: 'failure' }, status: 401
end
end
end
end
end
sSLを使用していないときはうまく機能しましたが、curl --LI http://foo/api/auth.json
にしようとすると、https
に適切にリダイレクトされますが、http://foo/api/auth
にリダイレクトされ続けます無限リダイレクトループで。
私のルートは単純に
get "api/auth"
get "api/check"
Rails 3.2.1 on Ruby 1.9.2 with nginx 0.7.65を使用しています。
このリクエストがHTTPSで終了したリクエストであるかどうかに関する情報を転送していません。通常、サーバーでは、「ssl on;」ディレクティブはこれらのヘッダーを設定しますが、結合ブロックを使用しています。
ラック(およびforce_ssl)は、以下によってSSLを決定します。
詳細については、 force_sslソース を参照してください。
結合ブロックを使用しているため、3番目の形式を使用する必要があります。試してください:
proxy_set_header X-Forwarded-Proto $scheme;
サーバーまたはロケーションブロックで nginxのドキュメントによる 。
これにより、ポート80の要求を受信するとヘッダーが「http」に設定され、443の要求を受信するとヘッダーが「https」に設定されます。
Nginx location @Unicorn
ブロックでこのディレクティブを設定してみてください:
proxy_set_header X-Forwarded-Proto https;
この同じ問題があり、Rackミドルウェアハンドラー(force_ssl
ではなく類似)を調査したところ、リクエストが既にnginxによってSSLとして処理されているかどうかを判断するためにヘッダーが設定されることを期待していることがわかりました。