rails config.force_ssl についてメモ
config.force_ssl = true
にすると、以下のようにActionDispatch::SSLというmiddlewareが有効になる
if config.force_ssl middleware.use ::ActionDispatch::SSL, **config.ssl_options, ssl_default_redirect_status: config.action_dispatch.ssl_default_redirect_status end
やってることは以下
rails/ssl.rb at v7.0.2.2 · rails/rails · GitHub
request.ssl?
がfalseの場合、httpsにリダイレクトする
if request.ssl? ... else return redirect_to_https request unless @exclude.call(request) ... end
Cookieにsecure 属性をつける
def flag_cookies_as_secure!(headers) if cookies = headers["Set-Cookie"] cookies = cookies.split("\n") headers["Set-Cookie"] = cookies.map { |cookie| if !/;\s*secure\s*(;|$)/i.match?(cookie) "#{cookie}; secure" else cookie end }.join("\n") end end
HTTP Strict Transport Security (HSTS) headerを追加する。
# https://tools.ietf.org/html/rfc6797#section-6.1 def build_hsts_header(hsts) value = +"max-age=#{hsts[:expires].to_i}" value << "; includeSubDomains" if hsts[:subdomains] value << "; preload" if hsts[:preload] value end
request.ssl?
の中身はというと、Rack::Request::Helpers にあるっぽい。
rack/request.rb at v2.2.2 · rack/rack · GitHub
こんな感じで、headerとか、X-Forwarded-Forにも対応してる。
def ssl? scheme == 'https' || scheme == 'wss' end def scheme if get_header(HTTPS) == 'on' 'https' elsif get_header(HTTP_X_FORWARDED_SSL) == 'on' 'https' elsif forwarded_scheme forwarded_scheme else get_header(RACK_URL_SCHEME) end end def forwarded_scheme allowed_scheme(get_header(HTTP_X_FORWARDED_SCHEME)) || allowed_scheme(extract_proto_header(get_header(HTTP_X_FORWARDED_PROTO))) end
なので、AWSでよくある、HTTPS -> ALB -> HTTP -> EC2 といった通信の場合は、内部ではHTTP通信でもRedirectされない。