Rails 앱에서 force_ssl로 무한 리디렉션 루프가 발생하는 이유는 무엇입니까?
API 컨트롤러가 SSL을 사용하도록하고 싶으므로 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를 통과합니다. 또한 force_ssl
ApiController에 지시문을 추가했습니다.
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"
nginx 0.7.65와 함께 Ruby 1.9.2에서 Rails 3.2.1을 사용하고 있습니다.
이 요청이 HTTPS 종료 요청인지 여부에 대한 정보를 전달하지 않습니다. 일반적으로 서버에서 "ssl on;" 지시문은 이러한 헤더를 설정하지만 결합 된 블록을 사용하고 있습니다.
랙 (및 force_ssl)은 다음을 통해 SSL을 결정합니다.
- If the request came in on port 443 (this is likely not being passed back to Unicorn from nginx)
- If ENV['HTTPS'] == "on"
- If the X-Forwarded-Proto header == "HTTPS"
See the force_ssl source for the full story.
Since you're using a combined block, you want to use the third form. Try:
proxy_set_header X-Forwarded-Proto $scheme;
in your server or location block per the nginx documentation.
This will set the header to "http" when you come in on a port 80 request, and set it to "https" when you come in on a 443 request.
Try setting this directive in your nginx location @unicorn
block:
proxy_set_header X-Forwarded-Proto https;
I had this same issue and investigating the Rack middleware handler (not force_ssl
but similar) I could see that it was expecting that header to be set to determine if the request was already processed as being SSL by nginx.
'program tip' 카테고리의 다른 글
__init__ 외부에서 새 속성 생성 방지 (0) | 2020.11.20 |
---|---|
ASP.NET MVC에서 업로드 된 파일의 유효성을 검사하는 방법은 무엇입니까? (0) | 2020.11.20 |
IE에서 로컬 저장소 콘텐츠보기 (0) | 2020.11.20 |
AngularJS 통화 필터 소수 / 센트 제거 (0) | 2020.11.19 |
매일 같은 시간에 작업을 수행하는 Python 스크립트 (0) | 2020.11.19 |