Development Update 3.1 => Obtaining a Reset password token is incorrect.

Decision

Thanks to this gist form of Stephen Harman, I got her job. devise_mail_helpers.rb

module Features module MailHelpers def last_email ActionMailer::Base.deliveries[0] end # Can be used like: # extract_token_from_email(:reset_password) def extract_token_from_email(token_name) mail_body = last_email.body.to_s mail_body[/#{token_name.to_s}_token=([^"]+)/, 1] end end end 

I added the devise_mail_helpers.rb file to the same folder as the function specifications, and wrote this specification.

 require 'devise_mail_helpers.rb' include Features include MailHelpers describe "PasswordResets" do it "emails user when requesting password reset" do user = FactoryGirl.create(:user) visit root_url find("#login_link").click click_link "Forgot your password?" fill_in "Email", :with => user.email click_button "Send instructions" current_path.should eq('/users/sign_in') page.should have_content("You will receive an email with instructions about how to reset your password in a few minutes.") last_email.to.should include(user.email) token = extract_token_from_email(:reset_password) # Here I call the MailHelper form above visit edit_password_url(reset_password_token: token) fill_in "user_password", :with => "foobar" fill_in "user_password_confirmation", :with => "foobar1" find('.signup_firm').find(".submit").click page.should have_content("Password confirmation doesn't match Password") end end 

This will take care of the specs to make it work in the browser, look at Dave's answer below.

Original question

In my 4 rails application, I updated the application to version 3.1 and ran rails s , after which I got the following:

 `raise_no_secret_key': Devise.secret_key was not set. Please add the following to your Devise initializer: (RuntimeError) config.secret_key = '--secret--' 

I added a secret key to the project initializer.

After that, I get the following error when trying to reset the password

 Reset password token is invalid 

It seems that the token sent by email is incorrect. Everything else works. I come in and go out like a warm knife with butter.

Update

Now I assume that it should be something with encryption reset_password_token Here from the function specification:

 user = FactoryGirl.create(:user, :reset_password_token => "something", :reset_password_sent_at => 1.hour.ago) visit edit_password_url(user, :reset_password_token => user.reset_password_token) fill_in "user_password", :with => "foobar" click_button "Change my password" page.should have_content("Password confirmation doesn't match Password") 

An error has occurred:

 Failure/Error: page.should have_content ("Password confirmation doesn't match Password") expected to find text "Password confirmation doesn't match Password" in "Reset password token is invalid" 

Any ideas on what I am missing?

+40
ruby-on-rails ruby-on-rails-4 devise rspec2 factory-bot
Sep 06 '13 at 15:47
source share
6 answers

You commented on my similar question a little back, and I found an answer that could help you.

Updating to version 3.1.0 left some “breakthrough” in the view, which I did not touch for a while. According to this blog post , you need to modify your Device @token to use @token instead of the old @resource.confirmation_token .

Find this in app/views/<user>/mailer/reset_password_instructions.html.erb and change it to something like:

 <p>Hello <%= @resource.email %>!</p> <p>Someone has requested a link to change your password, and you can do this through the link below.</p> <p><%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @token) %></p> <p>If you didn't request this, please ignore this email.</p> <p>Your password won't change until you access the link above and create a new one.</p> 

This should fix any token confirmation problems you have. This will probably also fix any issues with unlocking or confirmation.

+91
Sep 07 '13 at 16:01
source share

FYI, if you are trying to send a reset token using other means (i.e., another email program), you can use such code (dug from the Devise source) in your User class:

 def send_invitation raw, enc = Devise.token_generator.generate(self.class, :reset_password_token) self.reset_password_token = enc self.reset_password_sent_at = Time.now.utc self.save(:validate => false) Notifier.signup_notification(contactable: self, token: raw).deliver end 
+8
Jan 06 '14 at 20:48
source share

I think you upgraded Devise to version v3.1, not v3.01, due to config.secret_key . Therefore, I think that this is somehow connected with a new development function - a secret key.
I found two commits for a secret key function that may be useful for a better understanding: https://github.com/plataformatec/devise/commit/32648027e282eb4c0f4f42e9c9cc0c961765faa8 https://github.com/plataformatec/devise/commit/d56641f5bb5f16b

You will probably find something useful for you at http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/ .
You can also grep reset_password_token at https://github.com/plataformatec/devise/compare/v3.0...v3.1.0 .

EDIT
Read on http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/ :

  • The sender-developer now receives one additional token argument on each method. If you set up the Devise mailer, you will have to upgrade it. All mailer views should also be updated to use @token , as shown here , instead of getting the token directly from the resource;
+7
Sep 07 '13 at 11:10
source share

I had this error on specs. I tried to manually set reset_password_token to the user so that I could just pass the token to edit_user_password_path . However, reset tokens are hashed, so manual configuration will not work. Unfortunately! To avoid this error, I set reset_token to the actual token generated, which is returned by user.send_reset_password_instructions .

Working specification:

 require 'spec_helper' feature 'User resets password' do scenario 'fills out reset form' do user = create(:user) reset_token = user.send_reset_password_instructions new_password = 'newpassword!' visit edit_user_password_path(user, reset_password_token: reset_token) fill_in :user_password, with: new_password fill_in :user_password_confirmation, with: new_password click_button 'Change my password' expect(page).to have_content( 'Your password was changed successfully. You are now signed in.' ) end end 
+7
Sep 23 '13 at 1:45
source share

In your reset password template, make sure the following content should fix:

= link_to 'Change my password', edit_password_url (@resource ,: reset_password_token => @token)

+1
Oct 17 '14 at 9:30 a.m.
source share

As others noted: the reason is that you need to change the view that generates mail, which includes a link to reset.

I saw this error because I still used the devise-i18n-views gem that generates the old link. Removing this jewel and using the looks that are now part of devise-i18n pearls solved the problem for me.

+1
Aug 23 '16 at 10:38 on
source share



All Articles