2013-04-25 08:40:53 -04:00
|
|
|
require 'active_support/core_ext/hash/except'
|
|
|
|
require 'active_support/core_ext/hash/slice'
|
|
|
|
|
2011-03-27 15:05:14 -04:00
|
|
|
module ActionController
|
2011-05-24 01:40:29 -04:00
|
|
|
# This module provides a method which will redirect browser to use HTTPS
|
2011-03-27 15:05:14 -04:00
|
|
|
# protocol. This will ensure that user's sensitive information will be
|
|
|
|
# transferred safely over the internet. You _should_ always force browser
|
|
|
|
# to use HTTPS when you're transferring sensitive information such as
|
|
|
|
# user authentication, account information, or credit card information.
|
|
|
|
#
|
2011-05-24 01:40:29 -04:00
|
|
|
# Note that if you are really concerned about your application security,
|
|
|
|
# you might consider using +config.force_ssl+ in your config file instead.
|
2011-03-27 15:05:14 -04:00
|
|
|
# That will ensure all the data transferred via HTTPS protocol and prevent
|
|
|
|
# user from getting session hijacked when accessing the site under unsecured
|
|
|
|
# HTTP protocol.
|
|
|
|
module ForceSSL
|
|
|
|
extend ActiveSupport::Concern
|
|
|
|
include AbstractController::Callbacks
|
|
|
|
|
2013-04-25 08:40:53 -04:00
|
|
|
ACTION_OPTIONS = [:only, :except, :if, :unless]
|
|
|
|
URL_OPTIONS = [:protocol, :host, :domain, :subdomain, :port, :path]
|
|
|
|
REDIRECT_OPTIONS = [:status, :flash, :alert, :notice]
|
|
|
|
|
2011-03-27 15:05:14 -04:00
|
|
|
module ClassMethods
|
|
|
|
# Force the request to this particular controller or specified actions to be
|
|
|
|
# under HTTPS protocol.
|
|
|
|
#
|
2012-02-23 07:57:36 -05:00
|
|
|
# If you need to disable this for any reason (e.g. development) then you can use
|
|
|
|
# an +:if+ or +:unless+ condition.
|
|
|
|
#
|
|
|
|
# class AccountsController < ApplicationController
|
2012-10-27 16:05:27 -04:00
|
|
|
# force_ssl if: :ssl_configured?
|
2012-02-23 07:57:36 -05:00
|
|
|
#
|
|
|
|
# def ssl_configured?
|
|
|
|
# !Rails.env.development?
|
|
|
|
# end
|
|
|
|
# end
|
2011-03-27 15:05:14 -04:00
|
|
|
#
|
2013-04-25 08:40:53 -04:00
|
|
|
# ==== URL Options
|
|
|
|
# You can pass any of the following options to affect the redirect url
|
|
|
|
# * <tt>host</tt> - Redirect to a different host name
|
|
|
|
# * <tt>subdomain</tt> - Redirect to a different subdomain
|
|
|
|
# * <tt>domain</tt> - Redirect to a different domain
|
|
|
|
# * <tt>port</tt> - Redirect to a non-standard port
|
|
|
|
# * <tt>path</tt> - Redirect to a different path
|
|
|
|
#
|
|
|
|
# ==== Redirect Options
|
|
|
|
# You can pass any of the following options to affect the redirect status and response
|
|
|
|
# * <tt>status</tt> - Redirect with a custom status (default is 301 Moved Permanently)
|
|
|
|
# * <tt>flash</tt> - Set a flash message when redirecting
|
2013-09-03 14:48:53 -04:00
|
|
|
# * <tt>alert</tt> - Set an alert message when redirecting
|
2013-04-25 08:40:53 -04:00
|
|
|
# * <tt>notice</tt> - Set a notice message when redirecting
|
|
|
|
#
|
|
|
|
# ==== Action Options
|
|
|
|
# You can pass any of the following options to affect the before_action callback
|
|
|
|
# * <tt>only</tt> - The callback should be run only for this action
|
|
|
|
# * <tt>except</tt> - The callback should be run for all actions except this action
|
|
|
|
# * <tt>if</tt> - A symbol naming an instance method or a proc; the callback
|
|
|
|
# will be called only when it returns a true value.
|
|
|
|
# * <tt>unless</tt> - A symbol naming an instance method or a proc; the callback
|
|
|
|
# will be called only when it returns a false value.
|
2011-03-27 15:05:14 -04:00
|
|
|
def force_ssl(options = {})
|
2013-04-25 08:40:53 -04:00
|
|
|
action_options = options.slice(*ACTION_OPTIONS)
|
2013-04-27 07:43:47 -04:00
|
|
|
redirect_options = options.except(*ACTION_OPTIONS)
|
2013-04-25 08:40:53 -04:00
|
|
|
before_action(action_options) do
|
2013-04-27 07:43:47 -04:00
|
|
|
force_ssl_redirect(redirect_options)
|
2011-03-27 15:05:14 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2012-05-31 10:06:17 -04:00
|
|
|
|
|
|
|
# Redirect the existing request to use the HTTPS protocol.
|
|
|
|
#
|
|
|
|
# ==== Parameters
|
2013-04-25 08:40:53 -04:00
|
|
|
# * <tt>host_or_options</tt> - Either a host name or any of the url & redirect options
|
|
|
|
# available to the <tt>force_ssl</tt> method.
|
|
|
|
def force_ssl_redirect(host_or_options = nil)
|
2012-05-31 10:06:17 -04:00
|
|
|
unless request.ssl?
|
2013-04-25 08:40:53 -04:00
|
|
|
options = {
|
2013-04-25 03:33:21 -04:00
|
|
|
:protocol => 'https://',
|
2013-04-25 08:40:53 -04:00
|
|
|
:host => request.host,
|
2013-04-25 03:33:21 -04:00
|
|
|
:path => request.fullpath,
|
2013-04-25 08:40:53 -04:00
|
|
|
:status => :moved_permanently
|
|
|
|
}
|
|
|
|
|
|
|
|
if host_or_options.is_a?(Hash)
|
|
|
|
options.merge!(host_or_options)
|
|
|
|
elsif host_or_options
|
2014-08-01 14:55:47 -04:00
|
|
|
options[:host] = host_or_options
|
2013-04-25 08:40:53 -04:00
|
|
|
end
|
2013-04-25 03:33:21 -04:00
|
|
|
|
2013-04-25 08:40:53 -04:00
|
|
|
secure_url = ActionDispatch::Http::URL.url_for(options.slice(*URL_OPTIONS))
|
2015-04-12 21:26:35 -04:00
|
|
|
flash.keep if respond_to?(:flash)
|
2013-04-25 08:40:53 -04:00
|
|
|
redirect_to secure_url, options.slice(*REDIRECT_OPTIONS)
|
2012-05-31 10:06:17 -04:00
|
|
|
end
|
|
|
|
end
|
2011-03-27 15:05:14 -04:00
|
|
|
end
|
2011-10-08 19:38:02 -04:00
|
|
|
end
|