Подтвердить что ты не робот

Обновление для разработки 3.1 => получение Reset токена пароля неверно.

Решение

Благодаря этой gist форме Стивена Хармана, я получил ее работу. 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

Это позаботится о спецификациях, чтобы заставить его работать в браузере, посмотрите на ответ Дейва ниже.

Оригинальный вопрос

В моем приложении 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 пароля

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"

Любые идеи о том, что мне не хватает?

4b9b3361

Ответ 1

Вы прокомментировали мой аналогичный вопрос немного назад, и я нашел ответ, который мог бы вам помочь.

Обновление до версии 3.1.0 оставило некоторый "рывок" в представлении, которое я не коснулся некоторое время. Согласно это сообщение в блоге, вам нужно изменить свою почтовую программу Device, чтобы использовать @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>

Это должно исправить любые проблемы с подтверждением на токен, которые у вас есть. Вероятно, это также устранит любые проблемы с разблокировкой или подтверждением.

Ответ 2

FYI, если вы пытаетесь отправить токен reset с помощью других средств (т.е. другой почтовой программы), вы можете использовать такой код (выкопанный из источника Devise) в вашем классе 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

Ответ 3

Думаю, вы обновили 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/.
Также вы можете grep reset_password_token на https://github.com/plataformatec/devise/compare/v3.0...v3.1.0.

ИЗМЕНИТЬ
Читайте на http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/:

  • Отправитель-разработчик теперь получает один дополнительный аргумент токена на каждом метод. Если вы настроили почтовую программу Devise, вам придется обновите его. Все просмотры мэйллеров также должны быть обновлены для использования @token, как показано здесь, вместо того, чтобы получать токен непосредственно из ресурс;

Ответ 4

У меня была эта ошибка по спецификациям. Я пытался вручную установить reset_password_token на пользователя, чтобы я мог просто передать токен в edit_user_password_path. Однако токены reset хэшируются, поэтому настройка вручную не будет работать. К сожалению! Чтобы избежать этой ошибки, я установил 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

Ответ 5

В своем шаблоне паролей reset убедитесь, что следующий контент должен исправить:

= link_to 'Изменить мой пароль', edit_password_url (@resource,: reset_password_token = > @token)

Ответ 6

Как отмечали другие: причина в том, что нужно изменить представление, которое генерирует почту, которая включает в себя ссылку на reset.

Я видел эту ошибку, потому что я все еще использовал драгоценный камень devise-i18n-views, который генерирует старую ссылку. Удаление этой драгоценности и использование взглядов, которые теперь являются частью жемчуга devise-i18n, решили проблему для меня.