0
votes

I have implemented Devise confirmable which is working properly. When a user signs up for the first time they get:

  • Re-directed to the application root at localhost:3000/en

  • Flash notice saying "A message with a confirmation link has been sent to your email address. Please open the link to activate your account."

So far so good.

I then updated the application controller:

class ApplicationController < ActionController::Base
    before_filter :authenticate_user!
end

Newly signed up users then find themselves redirected to localhost:3000/en/users/sign_in, with the confusing message "You need to sign in or sign up before continuing."

I've been browsing the Devise how to's but haven't yet cracked it. What is the simplest way to fix this problem?

Update

Here is more detail of the Application Controller:

class ApplicationController < ActionController::Base
  protect_from_forgery                                  
  before_filter :authenticate_user!
  before_filter :set_i18n_locale_from_params

  rescue_from CanCan::AccessDenied do |exception|
    flash[:error] = "Access denied!"
    redirect_to root_url
  end

  protected

  def set_i18n_locale_from_params
        ...
  end
end

Update

Here is the log as requested.

Started POST "/en/users" for 127.0.0.1 at 2012-10-05 17:28:37 +0100
[17:28:37] Processing by Devise::RegistrationsController#create as HTML
[17:28:37]   Parameters: {"utf8"=>"✓", "authenticity_token"=>"xUGLBMvZVWrtqLWpnAsa7R361QaGrOz/aVfEwvlS6xY=", "user"=>{"email"=>"[email protected]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up", "locale"=>"en"}
[17:28:37]    (0.1ms)  BEGIN
[17:28:37]   User Exists (0.6ms)  SELECT 1 AS one FROM "users" WHERE "users"."email" = '[email protected]' LIMIT 1
[17:28:37]   User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."confirmation_token" = 'a2XPMojypDn6uzzVAqcs' LIMIT 1
[17:28:37]   SQL (16.6ms)  INSERT INTO "users" ("confirmation_sent_at", "confirmation_token", "confirmed_at", "created_at", "current_sign_in_at", "current_sign_in_ip", "email", "encrypted_password", "failed_attempts", "last_sign_in_at", "last_sign_in_ip", "locale", "locked_at", "remember_created_at", "reset_password_sent_at", "reset_password_token", "role", "sign_in_count", "unconfirmed_email", "unlock_token", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21) RETURNING "id"  [["confirmation_sent_at", Fri, 05 Oct 2012 16:28:38 UTC +00:00], ["confirmation_token", "a2XPMojypDn6uzzVAqcs"], ["confirmed_at", nil], ["created_at", Fri, 05 Oct 2012 16:28:38 UTC +00:00], ["current_sign_in_at", nil], ["current_sign_in_ip", nil], ["email", "[email protected]"], ["encrypted_password", "$2a$10$HnsOCZgVTaEg9bniVzBe7OKIvw4x5hdAqjwrCG14eQDCvSTz8mxdu"], ["failed_attempts", 0], ["last_sign_in_at", nil], ["last_sign_in_ip", nil], ["locale", nil], ["locked_at", nil], ["remember_created_at", nil], ["reset_password_sent_at", nil], ["reset_password_token", nil], ["role", 0], ["sign_in_count", 0], ["unconfirmed_email", nil], ["unlock_token", nil], ["updated_at", Fri, 05 Oct 2012 16:28:38 UTC +00:00]]
[17:28:37]   Rendered devise/mailer/confirmation_instructions.html.erb (0.8ms)
[17:28:37] 
Sent mail to ...
[17:28:37]    (0.8ms)  COMMIT
[17:28:37] Redirected to http://localhost:3000/en
[17:28:37] Completed 302 Found in 5050ms (ActiveRecord: 0.0ms)
[17:28:42] 

Started GET "/en" for 127.0.0.1 at 2012-10-05 17:28:42 +0100
[17:28:42] Processing by PageController#index as HTML
[17:28:42]   Parameters: {"locale"=>"en"}
[17:28:42] Completed 401 Unauthorized in 0ms
[17:28:42] 

Started GET "/users/sign_in" for 127.0.0.1 at 2012-10-05 17:28:42 +0100
[17:28:42] Processing by Devise::SessionsController#new as HTML
[17:28:42]   Rendered devise/shared/_links.erb (0.9ms)
[17:28:42]   Rendered devise/sessions/new.html.erb within layouts/application (6.8ms)
[17:28:42] Completed 200 OK in 22ms (Views: 20.0ms | ActiveRecord: 0.0ms)

In routes.rb I have:

root :to => "page#index"

So what's happening is that PageController#index is redirecting the user to sign in. So the question boils down to how to exempt only this from :authenticate_user! in the Application Controller.

Resolution

So thanks to jibiel and this question the answer is:

  class PageController < ApplicationController
    skip_before_filter :authenticate_user!
  end

Simples!

1

1 Answers

2
votes
before_filter :authenticate_user!, :unless => :devise_controller?

And devise will handle authentications on its controller actions by himself. Otherwise you're overriding them as they're prepended to your before_filter.