Specify "Confirmation token is invalid" when the user signs up

Using Rails 4 and Devise 3.1.0 in my web application. I wrote a cucumber test to test the user; it doesn’t work when the "confirm my account" link is called to the email address.

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 "no-reply@mysite.com" # 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$ 

This error is reproduced when I log in manually through the web server, so it does not seem to be a cucumber problem.

I would like to:

  • The user has the opportunity to confirm his account with one click via this link by e-mail.
  • If the user has verified their account, log in to the account.

I have a setup:

  • Latest developer code from GitHub (3.1.0, ref 041fcf90807df5efded5fdcd53ced80544e7430f)
  • User class implementing confirmable
  • Using the default confirmation controller (I have not defined my own custom one.)

I read these posts:

And they tried:

  • Setting config.allow_insecure_tokens_lookup = true in my Devise initializer, which causes an "unknown method" error on startup. Plus it sounds like it's just a temporary fix, so I would like to avoid using it.
  • Cleared my DB and started from scratch (so there are no old tokens)

Update:

Checking the confirmation token stored on User after registration. The email token corresponds to the database token. According to the above posts, Devise does not suggest a new behavior, and instead, it should generate a second token based on the email token. This is suspicious. Running User.confirm_by_token('[EMAIL_CONFIRMATION_TOKEN]') returns a user who has errors "@messages = {: confirm_token => [" invalid "]}", which, apparently, is the source of the problem.

Token mismatch appears to be the heart of the problem; running the following code in the console to manually change the User_token confirmation results in a successful confirmation confirmation.

 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 

So why does it first save the invalid confirmation token in the database? I am using a custom registration controller ... maybe there is something in it that causes it to install incorrectly?

routes.rb

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

users / 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 
+42
ruby-on-rails devise devise-confirmable
Sep 05 '13 at 1:55
source share
2 answers

Therefore, updating to version 3.1.0 left some “breakthrough” in the view, which I did not touch at that time.

According to this blog post , you need to modify the Devise @token to use @token instead of the old @resource.confirmation_token .

Find this in app/views/<user>/mailer/confirmation_instructions.html.erb and change it to something like:

 <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> 

This should fix any token confirmation problems you have. This will probably also fix any problems with unlocking or reset.

+96
Sep 07 '13 at 15:57
source share

A friend of mine just found this question and emailed me a question about whether I understood this, which reminded me that I never submitted my own answer, so :)

I have finished resetting the token and using send to get the original token. This is ugly, but it works in punch mode for 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 
0
Dec 20 '15 at 19:49
source share



All Articles