3

I'm creating a Rails 3 site that allows a company to update some of its web pages, and I've used AuthLogic to take care of logging users & out.

For most traffic to our site, we don't need to use any encryption because we're not transmitting sensitive information. However, while a user is logging in, I figure it's important to use encryption to keep their password safe. Also, from what I understand it's important to keep all traffic encrypted once a user is logged in (to avoid someone stealing their cookies and getting authenticated as them).

The stackoverflow question "Rails 3 SSL Deprecation" has some helpful advice on using SSL with Rails 3, but I'm trying to figure out how to encrypt all traffic once a user is logged in (or logging in, etc.) but no traffic when no user is presently logged in. I can't see how to do this kind of conditional routing.

Community
  • 1
  • 1
Ben Coppock
  • 939
  • 11
  • 23

2 Answers2

1

You can check the protocol in a before filter :

before_filter do
  unless request.protocol == 'https://'
    redirect_to 'my_page_with_https'
  end
end

But this is maybe a little bit overkill. I don't know the cost of calling this kind of filter on each request.

aurels
  • 801
  • 7
  • 15
1

You need to ensure that you set your session to :secure => true, so that it will only be sent over the HTTPS protocol. Once you do that, you don't have to enforce ssl for all traffic (since the browser will determine whether to send it). You only need to enforce it on the controllers or actions that depend on the session.

To enforce HTTPS, use something like the ssl_requirement gem.

If you want to enforce HTTPS for all traffic once a user is signed in, then you'll probably need to set a non-secure cookie to test whether to enforce HTTPS.

class ApplicationController < ActionController::Base
  def ssl_required?
    # Allow HTTP, but enforce HTTPS for users with the 'ssl' cookie set
    # current_user probably isn't needed here
    Rails.env.production? && (current_user || cookies[:ssl])
  end
end

class AccountsController < ApplicationController
  def login
    if current_user = User.authenticate(user, password)
      # This isn't required for AccountsController,
      # because it enforces HTTPS below.
      cookies[:ssl] = '1'
    end
  end

  def logout
    cookies.delete(:ssl)
  end

  # Enforce HTTPS for the Accounts controller
  def ssl_required?
    Rails.env.production?
  end
end
jamesnov
  • 11
  • 3