Devise: reset_password_by_token not working

Created on 27 Feb 2017  ·  6Comments  ·  Source: heartcombo/devise

Hello,
I'm using devise 4.2.0 (rails 5.0.1) and i'm facing a problem resetting the password. I always receive a message telling that reset_password_token is invalid. I'm getting this result either with the default devise edit password view or with a custom one specifying in my form f.input :reset_password_token, as: :hidden (using simple_form).

In Devise::Models::Recoverable::ClassMethods -> reset_password_by_token i can find these lines:

original_token       = attributes[:reset_password_token]
reset_password_token = Devise.token_generator.digest(self, :reset_password_token, original_token)
recoverable = find_or_initialize_with_error_by(:reset_password_token, `reset_password_token)

if i replace them with:

original_token       = attributes[:reset_password_token]
recoverable = find_or_initialize_with_error_by(:reset_password_token, original_token)

everything works fine.

I'm doing something bad? or there is a problem with this module?
Thank you for your support.

Most helpful comment

@suzan2go thank you so much! You're right!

All 6 comments

Can you please share your devise/passwords/edit.html.erb file.

Sure,
The following is the code I'm using.

= simple_form_for(resource, as: resource_name, url: password_path(resource_name), method: :put do |f|
  = f.input :reset_password_token, as: :hidden
  = f.error_notification
  %input#account_password.form-control{name: "account[password]", type: "text", value: ""}/
  %input#account_password_confirmation.form-control{name: "account[password_confirmation]", type: "text", value: ""}/

  %button.btn.btn-primary.px-2{type: "submit"}= t('specific.devise.update_password.button_text')

Using a debugger i can see that in Devise::Models::Recoverable::ClassMethods -> reset_password_by_token the reset_password_token arrives as is stored in the database. In my opinion the problem is in the following line that changes the token:

reset_password_token = Devise.token_generator.digest(self, :reset_password_token, original_token)

Thank you for your help.

Use this line
<%= f.hidden_field :reset_password_token, value: (params[:reset_password_token] || params[:user][:reset_password_token]) %>

Instead of this line
= f.input :reset_password_token, as: :hidden

I hope it will work for you.

The problem isn't there, even if i use the default devise view it doesn't work. In the controller i get the token correctly. I forgot to specify before that i'm not using the standard User model, but a model Account as my resource .

@tenda89 I had the same problem.
Please check your reset_password_instructions.html.erb . In Devise 4.2, we have to use @token created here (https://github.com/plataformatec/devise/blob/88724e10adaf9ffd1d8dbfbaadda2b9d40de756a/lib/devise/models/recoverable.rb#L83), not @resouce.reset_password_token

# wrong
  = link_to t('.action', :default => "Change my password"), edit_password_url(@resource, reset_password_token: @resource.reset_password_token))

# correct
  = link_to t('.action', :default => "Change my password"), edit_password_url(@resource, reset_password_token: @token))

@suzan2go thank you so much! You're right!

Was this page helpful?
0 / 5 - 0 ratings