Обновление до devise 3.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
в ту же папку, технические характеристики и спецификации.
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
это заботится о спецификациях, чтобы заставить его работать в браузере, посмотрите на ответ Дэйва ниже.
Исходный Вопрос
в моем приложении 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
похоже, что токен, который отправляется по электронной почте, неверен. Все остальное работает. Я вхожу и выхожу, как теплый нож в масле.
обновление
теперь я думаю, что это должно быть что-то с шифрованием 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"
есть идеи о том, чего мне не хватает?
6 ответов
Вы прокомментировали мой подобный вопрос немного назад, и я нашел ответ, который может помочь вам также.
обновление до Devise 3.1.0 оставило некоторый "cruft" в представлении, к которому я не прикасался некоторое время. Согласно этот блог, вам нужно изменить свой Devise mailer для использования @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>
это должно исправить любые маркеры у тебя проблемы с подтверждением. Это, вероятно, исправить любые проблемы разблокировки или подтверждения токена, а также.
FYI, если вы пытаетесь отправить токен пароля сброса с помощью другого средства (т. е. другого почтовика), вы можете использовать такой код (выкопанный из источника 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
. Поэтому я думаю, что это как - то связано с новой функцией-секретным ключом.
Я нашел две фиксации для функции секретного ключа, которые могут быть полезны для лучшего понимания:
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 on 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 теперь получает один дополнительный аргумент токена на каждом метод. Если вы настроили Devise mailer, вам придется обновлять его. все почтовые представления также должны быть обновлены для использования @ 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
в шаблоне devise reset password убедитесь, что следующее содержимое должно быть исправлено:
=link_to 'изменить пароль', edit_password_url (@resource, :reset_password_token => @token)
Как отмечали другие: причина в том, что представление, которое генерирует почту, которая включает ссылку сброса пароля, необходимо изменить.
я увидел эту ошибку, потому что я все еще использовал devise-i18n-views
gem, который генерирует старую ссылку. Удаление этого драгоценного камня и опираясь на мнения, которые теперь являются частью devise-i18n
gem решил проблему для меня.