Skip to content

Instantly share code, notes, and snippets.

@drymar
Created June 29, 2016 13:47
Show Gist options
  • Save drymar/023461d5d443dbaf1a8e2ba0f8016045 to your computer and use it in GitHub Desktop.
Save drymar/023461d5d443dbaf1a8e2ba0f8016045 to your computer and use it in GitHub Desktop.
Use SSL in Rails development. First: to create a local SSL certificate and start a SSL webserver checkout *shell.sh*. Second: to configure Rails checkout *rails.rb*
# To enable SSL in Rails you could now simply use *force_ssl* in your
# ApplicationController but there is two more things to think about:
# In development our SSL webserver is running on port 3001 so we would
# actually need to use *force_ssl port: 3001* but then this wouldn't
# work for production.
# Also there is a good chance you might not always want to use SSL in development
# so it would be nice if we could just enable or disable SSL in the config.
# To make all this work first copy the file *ssl_with_configured_port.rb* to
# your *lib* directory. Second to enable SSL add *config.use_ssl = true*
# to your environment config. You will probably add it
# to *config/environment/production.rb* and maybe to *development.rb* if you want
# to test SSL in development. Now add the port of your development SSL site to
# *config/environment/development.rb* like so *config.ssl_port = 3001*.
# Finally change your ApplicationController to look like this:
class ApplicationController < ActionController::Base
# Include the module we just created.
include SSLWithConfiguredPort
# Instead of *force_ssl* we use *force_ssl_with_configured_port* that will read
# the SSL port from the config. We added a *if* so that this will only run
# if the *use_ssl?* method below returns true.
force_ssl_with_configured_port if: :use_ssl?
private
# This will return true if the config has *config.use_ssl = true*
def use_ssl?
Rails.application.config.try(:use_ssl).is_a?(TrueClass)
end
end
# Create a ssh directory in your app directory
mkdir .ssl
# Create a self signed certificate
# It'll ask you for address data and you can specify what you like but for
# *Common Name* use: "localhost.ssl"
openssl req -new -newkey rsa:2048 -sha1 -days 365 -nodes -x509 -keyout .ssl/localhost.key -out .ssl/localhost.crt
# Add localhost.ssl to /private/etc/hosts
echo "127.0.0.1 localhost.ssl" | sudo tee -a /private/etc/hosts
# That's it. Now you need to run two development webservers one for
# HTTP and the other for HTTPS SSL request. I recommend *Thin* as the webserver
# because the Rails default webserver won't understand SSL.
# If you don't have Thin add *gem 'thin', group: :development* to your GEMFILE
# and run
bundle install
# To start the regular webserver just use
bundle exec rails s
# To start the SSL webserver open another terminal window and run
bundle exec thin start -p 3001 --ssl --ssl-verify --ssl-key-file .ssl/localhost.key --ssl-cert-file .ssl/localhost.crt
# Now the HTTP website is available via *localhost:3000* in your browser and the
# SSL website is running under *localhost:3001*.
# In development the website probably runs on a non default ssl port and you would
# have to specify that port all the time when doing *force_ssl* in development.
# So to make this more easy you can configure the SSL port in your
# *config/environment/development.rb*. For example if it runs on port 3001 use
#
# config.ssl_port = 3001
#
# and then include this module in your ApplicationController and use
# *force_ssl_with_configured_port* instead of *force_ssl*
#
# class ApplicationController < ActionController::Base
# include SSLWithConfiguredPort
# force_ssl_with_configured_port
#
# ...
# end
module SSLWithConfiguredPort
extend ActiveSupport::Concern
module ClassMethods
def force_ssl_with_configured_port(options = {})
options[:port] = Rails.application.config.ssl_port if options[:port].blank? && Rails.application.config.try(:ssl_port).present?
force_ssl options
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment