解决方案
感谢这个gist形式的Steven Harman,我得到了它的工作。 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
添加到与功能规格相同的文件夹中,并编写了此规范。
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--'
我将密钥添加到设计初始化程序。
在此之后,当我尝试重置密码时出现以下错误
Reset password token is invalid
似乎在电子邮件中发送的令牌不正确。其他一切都在发挥作用。我像一把温暖的刀槽黄油一样进出。
更新
现在我想,它必须是加密reset_password_token
来自功能规范的内容:
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"
关于我缺少的任何想法?
答案 0 :(得分:91)
您之前评论过my similar question,我找到了一个可能对您有所帮助的答案。
升级到Devise 3.1.0在一段时间内我没有碰过的视图中留下了一些“残酷”。根据{{3}},您需要更改您的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>
这应该可以解决您遇到的任何基于令牌的确认问题。这也可能解决任何解锁或确认令牌问题。
答案 1 :(得分:8)
仅供参考,如果您尝试通过其他方式(即不同的邮件程序)发送重置密码令牌,您可以在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
答案 2 :(得分:7)
我猜你已经将Devise升级到v3.1而不是v3.01,因为config.secret_key
。所以我认为它与新的设计功能 - 秘密密钥有关
我找到了两个秘密密钥功能提交,有助于更好地理解:
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/上找到对您有用的内容 您也可以在https://github.com/plataformatec/devise/compare/v3.0...v3.1.0上点击 reset_password_token 。
修改强>
继续阅读http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/:
答案 3 :(得分:7)
我在规格上有这个错误。我试图在User上手动设置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
答案 4 :(得分:1)
在您的设计重设密码模板中,请确保以下内容应该更正:
= link_to&#39;更改我的密码&#39;,edit_password_url(@resource,:reset_password_token =&gt; @token)
答案 5 :(得分:1)
正如其他人所说:原因是需要更改生成包含重置密码链接的邮件的视图。
我看到了这个错误,因为我还在使用生成旧链接的devise-i18n-views
gem。删除该gem并依赖现在是devise-i18n
gem的一部分的视图为我解决了这个问题。