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.
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.
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
.
I change @resource.confirmation_token
to @token
then it works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With