Skip to content

Instantly share code, notes, and snippets.

@mrrooijen
Created June 20, 2011 03:41
Show Gist options
  • Save mrrooijen/1035084 to your computer and use it in GitHub Desktop.
Save mrrooijen/1035084 to your computer and use it in GitHub Desktop.
Secure with SSL (Subdomain and Protocol) in Rails 3.1
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :secure_with_ssl
private
def secure_with_ssl
if request.subdomain != 'secure' or request.protocol != 'https'
redirect_to :subdomain => 'secure', :protocol => 'https'
end
end
end
@stephensprinkle-zz
Copy link

Just tried to implement your gist and it's causing two subdomains to be added -- such as secure.secure.example.com.

Any thoughts?

@stephensprinkle-zz
Copy link

Dumb mistake on my part...forgot in development that localhost would be considered the tld without .local appended. Great gist btw!

@mrrooijen
Copy link
Author

Thanks. By the way I believe that there is a built-in feature in Rails that handles redirection to the https protocol.

In your config/application.rb

config.force_ssl = true

Or place the above line in config/environments/production.rb if you only want the redirection to occur in production.

I'd assume it'd properly handle your root-level- and subdomains right out of the box.

(I believe this feature became available as of Rails 3.1, but I wrote this little snippet prior to reading up on the new additions at that time.)

@stephensprinkle-zz
Copy link

Fantastic, any idea if there is a per controller override for ssl as well if I go this route?

My thinking thus far is that I'll have it turned off for my public landing page, but on for everything else.

@mrrooijen
Copy link
Author

I believe I saw it here:

http://railscasts.com/episodes/270-authentication-in-rails-3-1

In Ryan's show notes:

application_controller.rb

force_ssl

private

def current_user
  @current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user

So I assume you can just use the force_ssl in any controller you want secured with ssl.

@stephensprinkle-zz
Copy link

Perfect, I'll give it a shot and let you know how it goes.

@stephensprinkle-zz
Copy link

Thanks again for the great gist & help.

An update --

I'm deploying to Heroku and had issues when utilizing force_ssl while still trying to retain controller specific ssl and had a 'too many redirects' issue with your original code above. In addition to this, I was also getting an error by utilizing 'request.protocol', so I modified things just a bit and all is working wonderfully now.

Controllers where I didn't need SSL --

def no_secure_subdomain_ssl
  if request.subdomain == 'secure' or request.ssl? == true
    redirect_to root_url(:host => request.domain, :protocol => 'http' ) 
  end
end

Controllers where I did need SSL --

def secure_subdomain_ssl
  if Rails.env.production?
    if request.subdomain != 'secure' or request.ssl? != true
      redirect_to :subdomain => 'secure', :protocol => 'https'
    end
  end
end

You'll notice in that last one I would check the Rails environment so that I wouldn't have issues in development.

Thanks again for all the help man!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment