Force SSL For a Rails Application with an Nginx Proxy

Posted by Ben Reubenstein Wed, 09 Apr 2008 16:52:00 GMT

Today I needed an entire site to run over SSL. I implemented a very straight forward before_filter that would catch a request and redirect to SSL if the request was not local and not already over SSL.

class ApplicationController < ActionController::Base

  before_filter :ensure_ssl

  def ensure_ssl
    redirect_to url_for params.merge({:protocol => 'https://'}) unless (request.ssl? || local_request?)
  end

end

All this resulted in was an endless loop, with the action constantly redirecting. I turned on some debugging:

logger.info url_for params.merge({:protocol => 'https://'}) # Confirming URL was correct
logger.info request.ssl? # Confirming the request was SSL
logger.info request.port # Checking the port the request came in on

It turned out request.ssl? was nil and the port was always 80. Nginx was not properly proxying along the fact that it was running over ssl. I added the following to my server / location declaration in the nginx.conf:

proxy_set_header X_FORWARDED_PROTO https;

Restart Nginx and request.ssl? returned true and request.port returned 443. I also just found some other great nginx examples from halorgium