升级到devise3.1 =>重置密码令牌无效
解
由于这个要求,史蒂文·哈曼,我得到了它的工作。 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
我将文件devise_mail_helpers.rb
添加到function规格所在的文件夹中,并编写了这个规范。
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
这照顾的规范,使其在浏览器中查看下面的Dave的答案。
原来的问题
在我的rails 4应用程序中,我已经升级到3.1并运行rails s
,然后我得到这个:
`raise_no_secret_key': Devise.secret_key was not set. Please add the following to your Devise initializer: (RuntimeError) config.secret_key = '--secret--'
我将秘密密钥添加到devise初始值设定项中。
之后,当我尝试重置密码时,出现以下错误
Reset password token is invalid
这似乎是在邮件中发送的令牌不正确。 其他一切正在工作。 我像一个温暖的刀槽黄油一样login和注销。
更新
现在我想,这是必须的东西encryption的reset_password_token
这里从function规格:
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")
发生的错误是:
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"
任何想法,我失踪?
您之前对我的类似问题进行了评论,我find了一个可能对您有帮助的答案。
升级到Devise 3.1.0,留下了一段时间以来我没有碰到过的东西。 根据这个博客文章 ,你需要改变你的devise邮件使用@token
而不是旧的@resource.confirmation_token
。
在app/views/<user>/mailer/reset_password_instructions.html.erb
它并将其更改为如下所示:
<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>
这应该修复您正在使用的任何基于令牌的确认问题。 这可能会解决任何解锁或确认令牌问题。
仅供参考,如果您尝试通过其他方式(即不同的邮件程序)发送重置密码令牌,则可以在您的User类中使用这样的代码(从Devise源代码中挖掘出来):
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
我猜你已经把Devise升级到v3.1而不是v3.01,因为config.secret_key
。 所以我认为这是与新的devisefunction – 密钥有关。
我发现了两个提交秘密密钥的function,可以帮助更好地理解: https : //github.com/plataformatec/devise/commit/32648027e282eb4c0f4f42e9c9cc0c961765faa8 https://github.com/plataformatec/devise/commit/d56641f514f54da04f778b2a9b816561df7910c2
也许你会在http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/上find对你有用的东西。;
你也可以通过https://github.com/plataformatec/devise/compare/v3.0…v3.1.0 grep reset_password_token 。
编辑
阅读http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/ :
- Devise邮件程序现在在每个方法上接收一个额外的标记参数。 如果你已经定制了Devise邮件,你将不得不更新它。 所有的邮件程序视图也需要更新为使用@token ,如图所示,而不是直接从资源获取令牌;
我在规格上有这个错误。 我试图在用户上手动设置reset_password_token
,这样我就可以将令牌传递给edit_user_password_path
。 但是,重置令牌被散列,因此手动设置将不起作用。 哎呀! 为了避免这个错误,我设置了reset_token
等于由user.send_reset_password_instructions
返回的实际标记。
工作规范:
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
在您的设备重置密码模板中,确保以下内容应该正确:
= link_to'更改我的密码',edit_password_url(@resource,:reset_password_token => @token)
正如其他人所指出的:原因是生成包含重置密码链接的邮件的视图需要更改。
我看到这个错误,因为我还在使用devise-i18n-views
gem,它会生成旧的链接。 去掉这个gem,依靠现在是devise-i18n
的一部分的意见,解决了我的问题。