La mise à niveau pour concevoir 3.1 => obtenir le mot de passe de réinitialisation du mot de passe est invalide

Solution

Grâce à cette forme géniale Steven Harman, je l’ai fait fonctionner. inventer_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 

J’ai ajouté le fichier devise_mail_helpers.rb au même dossier que les spécifications des fonctionnalités et j’ai écrit cette spécification.

 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 

Cela prend soin des spécifications, pour que cela fonctionne dans le navigateur, regardez la réponse de Dave ci-dessous.

Question originale

Dans mon application rails 4, j’ai mis à niveau le dispositif vers la version 3.1 et utilisé les rails s , puis j’ai obtenu ceci:

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

J’ai ajouté la clé secrète à l’initialiseur du lecteur.

Après cela, j’obtiens l’erreur suivante lorsque j’essaie de réinitialiser le mot de passe

 Reset password token is invalid 

Il semble que le jeton envoyé dans le courrier électronique ne soit pas correct. Tout le rest fonctionne. Je me connecte et je sors comme un couteau chaud au beurre.

Mettre à jour

Maintenant, je suppose que cela doit être quelque chose avec le cryptage de la reset_password_token Ici, à partir des spécifications de la fonctionnalité:

 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") 

l’erreur est survenue:

 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" 

Des idées sur ce qui me manque?

Vous avez commenté ma question un peu plus tôt et j’ai trouvé une réponse qui pourrait vous aider également.

La mise à niveau vers Devise 3.1.0 a laissé des traces dans un point que je n’avais pas touché depuis longtemps. Selon ce billet de blog , vous devez modifier votre logiciel de messagerie Devise pour utiliser @token au lieu de l’ancien @resource.confirmation_token .

Trouvez cela dans app/views//mailer/reset_password_instructions.html.erb et changez-le en quelque chose comme:

 

Hello <%= @resource.email %>!

Someone has requested a link to change your password, and you can do this through the link below.

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

If you didn't request this, please ignore this email.

Your password won't change until you access the link above and create a new one.

Cela devrait résoudre tous les problèmes de confirmation liés aux jetons que vous rencontrez. Cela corrigera probablement tout problème de jeton de délocking ou de confirmation.

FYI, si vous essayez d’envoyer un jeton de réinitialisation du mot de passe par un autre moyen (par exemple, un mailer différent), vous pouvez utiliser du code comme celui-ci (extrait de la source Devise) dans votre classe User:

 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 

Je suppose que vous avez mis à jour Devise vers la v3.1 et non la v3.01, à cause de config.secret_key . Donc, je pense que c’est en quelque sorte lié à la nouvelle fonctionnalité de dispositif – clé secrète.
J’ai trouvé deux commits pour la fonction de clé secrète qui peuvent être utiles pour mieux comprendre: https://github.com/plataformatec/devise/commit/32648027e282eb4c0f4f42e9c9cc0c961765faa8 https://github.com/plataformatec/devise/commit/d56641f514f54da04f778b2a9b816561df7910c2

Vous trouverez probablement aussi quelque chose d’utile sur http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/ .
Vous pouvez également grep reset_password_token sur https://github.com/plataformatec/devise/compare/v3.0…v3.1.0 .

MODIFIER
Lire sur http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/ :

  • Le logiciel de messagerie Devise reçoit désormais un argument de jeton supplémentaire sur chaque méthode. Si vous avez personnalisé le logiciel de messagerie Devise, vous devrez le mettre à jour. Toutes les vues de courrier doivent également être mises à jour pour utiliser @token , comme indiqué ici , au lieu d’obtenir directement le jeton de la ressource.

J’ai eu cette erreur sur les spécifications. J’essayais de définir manuellement reset_password_token sur User pour que je puisse simplement passer le jeton à edit_user_password_path . Cependant, les jetons de réinitialisation sont hachés. Par conséquent, le réglage manuel ne fonctionnera pas. Oops! Pour éviter cette erreur, j’ai défini reset_token sur le jeton réel généré par user.send_reset_password_instructions .

Spec de travail:

 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 

Dans votre modèle de réinitialisation de mot de passe, assurez-vous que le contenu suivant est correct:

= link_to ‘Changer mon mot de passe’, edit_password_url (@resource,: reset_password_token => @token)

Comme d’autres l’ont noté: la raison en est que la vue qui génère le courrier contenant le lien de réinitialisation du mot de passe doit être modifiée.

J’ai vu cette erreur parce que j’utilisais toujours la gem de devise-i18n-views , qui génère l’ancien lien. Supprimer ce joyau et me fier aux vues qui font maintenant partie de la gemme d’ devise-i18n résolu le problème pour moi.