Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Devise confirmation_token is invalid

My User.rb:

class User < ActiveRecord::Base

    devise :database_authenticatable, :registerable,:confirmable,:token_authenticatable,
     :recoverable, :rememberable, :trackable, :validatable, :authentication_keys => [:name]

My routes:

devise_for :users, :controllers => { :sessions => "sessions", :confirmations => "confirmations", :passwords => "passwords", :registrations => "registrations" }

My ConfirmationsController is a standard controller but with different redirect.

I have link on my email like:

/users/confirmation?confirmation_token=167bad44a15e02b0bd570b51e1bf927b88368d8855d92b9833a24017a2bad4be

In database user has

confirmation_token:167bad44a15e02b0bd570b51e1bf927b88368d8855d92b9833a24017a2bad4be

But when i click on that link i only see page with:

Resend confirmation instructions
 Confirmation token is invalid

What i dont do - what else i have to set.

CONFIRMATIONCONTROLLER:

def resource_params
 params.require(:user).permit(:confirmation_token)
   end
   private :resource_params


  def show
self.resource = resource_class.confirm_by_token(params[:confirmation_token])

if resource.errors.empty?
  set_flash_message(:notice, :confirmed) if is_navigational_format?
  sign_in(resource_name, resource)
  session['new_user'] = true
  respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
else
  respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render :new }
end
  end

  protected
    # The path used after resending confirmation instructions.
    def after_resending_confirmation_instructions_path_for(resource_name)
      new_registration_path(resource_name)
    end

I say "standard controller" because when i remove it and do not use custom controller problem is that same.

like image 456
Wordica Avatar asked Aug 22 '13 20:08

Wordica


3 Answers

Which version of devise are you using? If you're on 3.1.0 or higher, this behavior is expected:

CHANGELOG.md

The tokens that are stored in the database are not supposed to match the tokens that you send in the confirmation e-mails. See devise/lib/devise/models/confirmable.rb, which now contains the following:

def confirm_by_token(confirmation_token)
  original_token     = confirmation_token
  confirmation_token = Devise.token_generator.digest(self, :confirmation_token, confirmation_token)

  confirmable = find_or_initialize_with_error_by(:confirmation_token, confirmation_token)

As you can see, the token that you pass in via query string params is consumed by the Devise.token_generator, and the result of that operation is what's compared with the token in the database to discover the user record.

It looks like it's temporarily possible (in 3.1 but not 3.2) to turn this off by setting

config.allow_insecure_token_lookup = true

in your devise initializer. But the default behavior has been changed to make devise more secure. See this blog post for a complete rundown of the security improvements in devise 3.1, including this change.

like image 180
gregates Avatar answered Nov 13 '22 15:11

gregates


You can use the solution below (setting config.allow_insecure_token_lookup = true) but, according to the Devise changelog, this will be only available temporarily.

The problem likely arose because you ran the devise generator to dump all of their views into yours back before they made these changes. Then you updated your Devise gem and all the back end stuff changed but your views didn't. Now all your devise-related views and mailers are out of date and won't work with the new token styles.

You can see the new emails at: https://github.com/plataformatec/devise/tree/master/app/views/devise/mailer. The major change is changing this line:

<p><%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @resource.confirmation_token) %></p>

to

<p><%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %></p>

The main difference is @resource.confirmation_token becomes just @token.

like image 33
Erik Trautman Avatar answered Nov 13 '22 14:11

Erik Trautman


I change @resource.confirmation_token to @token then it works.

like image 2
scottxu Avatar answered Nov 13 '22 14:11

scottxu