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

Указать "Подтверждающий токен недействителен", когда пользователь подписывается

Использование Rails 4 и Devise 3.1.0 в моем веб-приложении. Я написал тест огурца, чтобы протестировать пользователя; он не работает, когда на адрес электронной почты вызывается ссылка "подтвердить мою учетную запись".

Scenario: User signs up with valid data                                                           # features/users/sign_up.feature:9
    When I sign up with valid user data                                                             # features/step_definitions/user_steps.rb:87
    Then I should receive an email                                                                  # features/step_definitions/email_steps.rb:51
    When I open the email                                                                           # features/step_definitions/email_steps.rb:76
    Then I should see the email delivered from "[email protected]"                                # features/step_definitions/email_steps.rb:116
    And I should see "You can confirm your account email through the link below:" in the email body # features/step_definitions/email_steps.rb:108
    When I follow "Confirm my account" in the email                                                 # features/step_definitions/email_steps.rb:178
    Then I should be signed in                                                                      # features/step_definitions/user_steps.rb:142
      expected to find text "Logout" in "...Confirmation token is invalid..." (RSpec::Expectations::ExpectationNotMetError)
     ./features/step_definitions/user_steps.rb:143:in `/^I should be signed in$

Эта ошибка воспроизводится, когда я регистрируюсь вручную через веб-сервер, поэтому она не кажется проблемой огурца.

Я бы хотел:

  • Пользователь имеет возможность одним щелчком подтвердить свою учетную запись через эту ссылку по электронной почте.
  • Если пользователь подтвердил свою учетную запись, войдите в аккаунт.

У меня есть настройка:

  • Последний код разработчика, от GitHub (3.1.0, ref 041fcf90807df5efded5fdcd53ced80544e7430f)
  • Класс User, реализующий confirmable
  • Использование контроллера подтверждения по умолчанию (я не определил свой собственный пользовательский.)

Я прочитал эти сообщения:

И попробовали:

  • Настройка config.allow_insecure_tokens_lookup = true в моем инициализаторе Devise, который вызывает ошибку "неизвестного метода" при запуске. Плюс это звучит так, как будто это только временное исправление, поэтому я бы хотел избежать его использования.
  • Очистил мою БД и начал с нуля (поэтому нет старых токенов)

Update:

Проверка маркера подтверждения, сохраненного на User после регистрации. Токен электронной почты соответствует токену БД. Согласно вышеприведенным сообщениям, новое поведение Devise не предполагает, и вместо этого оно должно генерировать второй токен на основе токена электронной почты. Это подозрительно. Запуск User.confirm_by_token('[EMAIL_CONFIRMATION_TOKEN]') возвращает пользователя, у которого установлены ошибки "@messages = {: confirm_token = > [" недействительно "]}", который, по-видимому, является источником проблемы.

Несовпадение жетонов, по-видимому, является сердцем проблемы; запуск следующего кода в консоли для ручного изменения подтверждения User_token приводит к успешному подтверждению подтверждения.

new_token = Devise.token_generator.digest(User, :confirmation_token, '[EMAIL_TOKEN]')
u = User.first
u.confirmation_token = new_token
u.save
User.confirm_by_token('[EMAIL_TOKEN]') # Succeeds

Итак, почему он сначала сохраняет неверный токен подтверждения в БД? Я использую пользовательский контроллер регистрации... может быть, есть что-то в нем, которое заставляет его неправильно устанавливать?

routes.rb

  devise_for  :users,
          :path => '',
          :path_names => {
            :sign_in => 'login',
            :sign_out => 'logout',
            :sign_up => 'register'
            },
          :controllers => {
            :registrations => "users/registrations",
            :sessions => "users/sessions"
          }

пользователи /registrations _controller.rb

class Users::RegistrationsController < Devise::RegistrationsController

  def create
    # Custom code to fix DateTime issue
    Utils::convert_params_date_select params[:user][:profile_attributes], :birthday, nil, true

    super
  end

  def sign_up_params
    # TODO: Still need to fix this. Strong parameters with nested attributes not working.
    #       Permitting all is a security hazard.
    params.require(:user).permit!
    #params.require(:user).permit(:email, :password, :password_confirmation, :profile_attributes)
  end
  private :sign_up_params
end
4b9b3361

Ответ 1

Поэтому обновление до версии 3.1.0 оставило некоторый "рывок" в представлении, которое я не коснулся в то время.

Согласно этот пост в блоге, вам нужно изменить почтовую программу Devise, чтобы использовать @token вместо старого @resource.confirmation_token.

Найдите это в app/views/<user>/mailer/confirmation_instructions.html.erb и измените его на что-то вроде:

<p>Welcome <%= @resource.email %>!</p>
<p>You can confirm your account email through the link below:</p>
<p><%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @token) %></p>

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

Ответ 2

Один мой друг только что нашел этот вопрос и отправил мне по электронной почте вопрос о том, понял ли я это, что напомнило мне, что я никогда не подавал свой собственный ответ, так вот:)

Я закончил сброс токена и используя send, чтобы получить исходный токен. Это уродливо, но он работает в режиме punch для devise (3.5.1).

26   it "should auto create org" do
27     email = FG.generate :email
28     visit new_user_registration_path
29     fill_in :user_name, with: 'Ryan Angilly'
30     fill_in :user_user_provided_email, with: email
31     fill_in :user_password, with: '1234567890'
32 
33     expect do
34       click_button 'Continue'
35     end.to change { Organization.count }.by(1)
36 
37     expect(page.current_path).to eq(confirmation_required_path)
38     u = User.where(email: email).first
39     u.send :generate_confirmation_token
40     email_token = u.instance_variable_get(:@raw_confirmation_token)
41     u.save!
42     os = u.organizations
43     expect(os.size).to eq(1)
44     visit user_confirmation_path(confirmation_token: email_token)
45     o = os.first
46 
47     u.reload
48     expect(u.confirmed?)
49     expect(page.current_url).to eq(organization_getting_started_url(o))
50   end