LogoDTreeLabs

Rails 6 deprecates controller level force_ssl option

Akshay MohiteBy Akshay Mohite in Rails on November 22, 2019

Previously, we were able to force_ssl to specific controller actions by using force_ssl callback at controller level. Rails 6 deprecates this option setting at controller level. This option to force_ssl is now available only at Rails application configuration level only.

Before Rails 6

Let’s say, we have a resource configured for posts.

# config/routes.rb
resources :posts

The controller has actions as given below.

  • Index action to list available posts
  • Create action to create a new post
class PostsController < ApplicationController
  def index
    # code to return list of available posts
  end

  def create
    # code to create a new post
  end
end

Let’s say, we want to create an action to be accessed with ssl only. This can be enforced using force_ssl option available as a callback at controller level with code given below.

class PostsController < ApplicationController

  force_ssl only: [:create]

  def index
    # code to return list of available posts
  end

  def create
    # code to create a new post
  end
end

As we can see, we have specified force_ssl with options only: [:index], this means Rails will force requests to use ssl protocol only for create action on posts controller.

Now, if we try to create a new post without using ssl then, it will throw an error as given below.

Filter chain halted as actionpack-5.1.5/lib/action_controller/metal/force_ssl.rb:65> rendered or redirected

Completed 301 Moved Permanently

After Rails 6

Rails 6 encourages us to use force_ssl option at config level to enable ssl throughout our application. We can set this option as given below.

# config/environments/production.rb
config.force_ssl = true

If we still use, force_ssl at controller level, it still works as expected but Rails throws a deprecation warning as given below.

DEPRECATION WARNING: Controller-level `force_ssl` is deprecated and will be removed from Rails 6.1. Please enable `config.force_ssl` in your environment configuration to enable the ActionDispatch::SSL middleware to more fully enforce that your application communicate over HTTPS. If needed, you can use `config.ssl_options` to exempt matching endpoints from being redirected to HTTPS. (called from <class:ConsumerController> at /Users/akshay/workplace/fiormarkets/app/controllers/consumer_controller.rb:5)

If we still want to disable ssl verification for certain endpoints, then we can use ssl_options at config level to achieve such behavior.

config.ssl_options = {
  redirect: {
    exclude: -> request { request.post? && request.path =~ /posts/ }
  }
}

This code block tells router to redirect to use ssl if request is of type post and includes posts path in ther request path.