Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 升级到设计3.1=>;获取重置密码令牌无效_Ruby On Rails_Devise_Ruby On Rails 4_Factory Bot_Rspec2 - Fatal编程技术网

Ruby on rails 升级到设计3.1=>;获取重置密码令牌无效

Ruby on rails 升级到设计3.1=>;获取重置密码令牌无效,ruby-on-rails,devise,ruby-on-rails-4,factory-bot,rspec2,Ruby On Rails,Devise,Ruby On Rails 4,Factory Bot,Rspec2,解决方案 多亏了史蒂文·哈曼的这份表格,我才得以顺利完成。 设计邮件帮助程序.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_ema

解决方案

多亏了史蒂文·哈曼的这份表格,我才得以顺利完成。 设计邮件帮助程序.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\u mail\u 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应用程序中,我已将Desive升级到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\u password\u令牌的加密有关:

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"

关于我缺少的东西有什么想法吗?

我想你已经将Desive升级到了v3.1而不是v3.01,因为
config.secret\u key
。因此,我认为这与新发明的功能——秘密密钥有关。
我发现了两个提交密钥功能,这有助于更好地理解:

也许你也会发现一些对你有用的东西。
您还可以grep重置密码\u令牌

编辑
请继续阅读:

  • designe邮件程序现在会在每个邮件上收到一个额外的令牌参数 方法。如果您已经定制了Desive mailer,您将不得不 更新它还需要更新所有邮件器视图以使用 @令牌,如图所示,而不是直接从 资源
您刚才发表了评论,我找到了一个可能对您也有帮助的答案

升级到Desive 3.1.0后,我有一段时间没碰过它了。根据,您需要将Desive mailer更改为使用
@token
,而不是旧的
@resource.confirmation\u token

app/views//mailer/reset\u password\u 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>
你好

有人请求一个链接来更改您的密码,您可以通过下面的链接来执行此操作

@token)%%>

如果您没有请求,请忽略此电子邮件

在访问上面的链接并创建新的链接之前,您的密码不会更改


这将修复您遇到的任何基于令牌的确认问题。这可能也会修复任何解锁或确认令牌问题。

我在规范中遇到了此错误。我试图在用户上手动设置
reset\u password\u token
,这样我就可以将token传递到
edit\u User\u password\u path
。但是,重置令牌是散列的,因此手动设置它将不起作用。哎呀!为了避免这个错误,我将
reset\u令牌
设置为等于
用户返回的实际生成的令牌。发送\u reset\u password\u指令

工作规范:

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

仅供参考,如果您试图通过其他方式(即不同的邮件发送)发送重置密码令牌,您可以在您的用户类中使用如下代码(从Desive source中挖掘):

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

在“设计重置密码”模板中,确保以下内容正确无误:


=链接到“更改我的密码”,编辑密码url(@resource,:reset\u password\u token=>@token)

正如其他人所指出的:原因是需要更改生成包含重置密码链接的邮件的视图


我看到这个错误是因为我仍然在使用生成旧链接的
designe-i18n-views
gem。删除该gem并依靠现在属于
designe-i18n
gem的视图为我解决了问题。

谢谢!我做了更多的调查。我知道Desive中的令牌处理发生了变化。所以,我开始在浏览器中工作。但是,如何测试它呢?。关于的评论中有一些提示。顺便说一下,我将3.01的拼写错误更正为3.1。这是使其在浏览器上正常工作的正确解决方案,但是如何测试它呢?乍一看,上面的Rspec测试看起来应该可以做到这一点。假设“无效令牌”问题已经解决,并且如果它在某个特定位置失败,您应该共享错误。从战略上讲,将Rspec或Cucumber与email_spec相结合应该可以让您自动测试这一点。我的链接问题,有更多关于如何用Cucumber测试Desive的信息。测试通过了。在我修复此问题之前,它的“无效令牌”失败。如果您使用自定义邮件程序,则必须通过def reset_password_指令(user、token、opts={})@token=token…..将令牌提供给视图。密钥为
self.reset_password_token=enc
,并设置
@token=raw
。非常感谢~!