Reputation: 46613
I've installed a self signed cert on my staging server. I'm using that to test my ssl set up. I'm using Devise 1.5 for logins and following this article on the devise wiki for ssl / http config.
The docs say:
And make sure to enable SSL on the server (Nginx, Apache, etc.). If the servers are not configured properly, Rails will not recognize the request as SSL (even if it is), and cause an infinite redirect loop.
Ok that sure looks like what is happening, but I strongly suspect I don't need to 'flip the switch' on SSL (this is an EngineYard instance). I have an SSL cert installed on the server.
I've checked the file /etc/nginx/servers/MyAppName.ssl.conf
and it has these lines:
ssl on;
ssl_certificate /etc/nginx/ssl/MyAppName.crt;
ssl_certificate_key /etc/nginx/ssl/MyAppName.key;
ssl_prefer_server_ciphers on;
ssl_protocols SSLv3 TLSv1;
So that looks ... right? I don't want to mess with it that's for sure.
My RegistrationsController has force_ssl :only => [:new, :create, :edit, :update]
, so all authentication actions should be forcing ssl as far as I can tell. SessionsController has force_ssl :only => [:new, :create]
.
I realize that there's a lot of moving parts here, but what should I look at next?
Here's the rails logs:
Started GET "/users/sign_in" for 98.246.164.160 at 2012-02-29 20:47:39 +0000
[29 Feb 20:47 23166 INFO] Processing by Devise::SessionsController#new as HTML
[29 Feb 20:47 23166 DEBUG] Parameters: {"action"=>"new", "controller"=>"devise/sessions"}
[29 Feb 20:47 23166 INFO] Redirected to https://ec2-xxx-xxx-106-255.us-west-2.compute.amazonaws.com/users/sign_in
[29 Feb 20:47 23166 INFO] Completed 301 Moved Permanently in 1ms
[29 Feb 20:47 23166 INFO]
Started GET "/users/sign_in" for 98.246.164.160 at 2012-02-29 20:47:39 +0000
[29 Feb 20:47 23166 INFO] Processing by Devise::SessionsController#new as HTML
[29 Feb 20:47 23166 DEBUG] Parameters: {"action"=>"new", "controller"=>"devise/sessions"}
[29 Feb 20:47 23166 INFO] Redirected to http://ec2-xxx-xxx-106-255.us-west-2.compute.amazonaws.com/users/sign_in
[29 Feb 20:47 23166 INFO] Completed 302 Found in 1ms
[29 Feb 20:47 23166 INFO]
Started GET "/users/sign_in" for 98.246.164.160 at 2012-02-29 20:47:39 +0000
[29 Feb 20:47 23166 INFO] Processing by Devise::SessionsController#new as HTML
[29 Feb 20:47 23166 DEBUG] Parameters: {"action"=>"new", "controller"=>"devise/sessions"}
[29 Feb 20:47 23166 INFO] Redirected to https://ec2-xxx-xxx-106-255.us-west-2.compute.amazonaws.com/users/sign_in
[29 Feb 20:47 23166 INFO] Completed 301 Moved Permanently in 1ms
Upvotes: 0
Views: 1647
Reputation: 1329
For those of you who arrived here via Google, let me post another possible cause of this problem that just wasted my day, hopefully it won't waste yours.
If you are using Passenger in production, and you configure it with a VirtualHost in Apache (in conf/httpd.conf for example), but you do NOT configure it in conf.d/ssl.conf, you could get the looping problem. The symptom you will have if this misconfiguration is causing your problem will be that request.ssl?
will always be false, even if you explicitly enter https in your request. To check your symptom, you can put a before_filter debugging hook in application_controller.rb with something like:
class ApplicationController < ActionController::Base
before_filter :check_ssl
def check_ssl
logger.info("==== ssl: #{request.ssl? }")
end
end
If it always logs ==== ssl: false
even when you send it a https://whatever
request, then the VirtualHost configuration might be your problem. If you put your DocumentRoot and Directory directives for your rails app in the VirtualHost in conf.d/ssl.conf, it will fix the problem. At least it did for me.
Upvotes: 1
Reputation: 46613
The solution to this lied in the 'ensure_proper_protocol' method from the gist. I renamed it to make it more readable and it looks like this:
def ssl_forced_action?
(params[:controller] == 'devise/sessions' && ['new', 'create'].include?(params[:action])) ||
(params[:controller] == 'devise/registrations' && ['new', 'create', 'edit', 'update'].include?(params[:action])) ||
(params[:controller] == 'users/omniauth_callbacks')
end
Note that the original used users/sessions
.
Upvotes: 0