Solution
Grâce à cela Gist de Steven Harman, je l'ai fait fonctionner. 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
J'ai ajouté le fichier devise_mail_helpers.rb
dans le même dossier que les spécifications des fonctionnalités et é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 en charge les spécifications, pour le faire fonctionner dans le navigateur, regardez la réponse de Dave ci-dessous.
Question d'origine
Dans mon Rails 4, j'ai mis à niveau la version 3.1 et exécuté Rails s
, alors 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 de devise.
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 l'e-mail ne soit pas correct. Tout le reste fonctionne. Je me connecte et me déconnecte comme un couteau au beurre chaud.
Mise à jour
Maintenant, je suppose que cela doit être quelque chose avec le cryptage du reset_password_token
Voici la spécification 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 survenue est:
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 similaire il y a un peu, et j'ai trouvé une réponse qui pourrait également vous aider.
La mise à niveau vers Devise 3.1.0 a laissé une certaine "cruauté" dans une vue que je n'avais pas touchée depuis un moment. Selon cet article de blog , vous devez changer votre logiciel de messagerie Devise pour utiliser @token
au lieu de l'ancien @resource.confirmation_token
.
Trouvez ceci dans app/views/<user>/mailer/reset_password_instructions.html.erb
et remplacez-le par quelque chose comme:
<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>
Cela devrait résoudre tous les problèmes de confirmation basés sur des jetons que vous rencontrez. Cela est également susceptible de résoudre tout problème de déverrouillage ou de jeton de confirmation.
Pour info, si vous essayez d'envoyer un jeton de réinitialisation de mot de passe via un autre moyen (c'est-à-dire un autre mailer), vous pouvez utiliser un code comme celui-ci (extrait de la source Devise), dans votre classe d'utilisateur:
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
J'ai eu cette erreur sur les spécifications. J'essayais de définir manuellement reset_password_token
sur l'utilisateur pour que je puisse simplement passer le jeton au edit_user_password_path
. Cependant, les jetons de réinitialisation sont hachés, donc le définir manuellement ne fonctionnera pas. Oups! Pour éviter cette erreur, j'ai défini reset_token
égal au jeton généré qui est retourné par user.send_reset_password_instructions
.
Spécifications 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
Je suppose que vous avez mis à niveau Devise vers la v3.1 et non la v3.01, à cause de config.secret_key
. Je pense donc que cela est en quelque sorte lié à la nouvelle fonctionnalité de conception - clé secrète.
J'ai trouvé deux validations pour une fonctionnalité de clé secrète qui peut être utile pour une meilleure compréhension: https://github.com/plataformatec/devise/commit/32648027e282eb4c0f4f42e9c9cc0c961765faa8https://github.com/plataformatec/devise/commit/d56641f514f54da04f778b2a9b816561df7910c2
Vous trouverez probablement quelque chose d'utile pour vous sur http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/ ainsi .
Vous pouvez également grep reset_password_token sur https://github.com/plataformatec/devise/compare/v3.0 ... v3.1. .
[~ # ~] modifier [~ # ~]
Lisez la suite http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/ :
Comme d'autres l'ont noté: la raison en est que la vue qui génère le courrier qui inclut le lien de réinitialisation du mot de passe doit être modifiée.
J'ai vu cette erreur car j'utilisais toujours le devise-i18n-views
gem, qui génère l'ancien lien. Supprimer ce joyau et s'appuyer sur les vues qui font maintenant partie du devise-i18n
gem a résolu le problème pour moi.
Dans votre modèle de réinitialisation de mot de passe, assurez-vous que le contenu suivant doit être correct:
= link_to 'Changer mon mot de passe', edit_password_url (@resource,: reset_password_token => @token)