rails gema current_user create confirmable ruby-on-rails devise devise-confirmable

ruby-on-rails - gema - rails devise login



Diseñar "El token de confirmación no es válido" cuando el usuario se registra (3)

Usando Rails 4 y Devise 3.1.0 en mi aplicación web. Escribí una prueba de Cucumber para probar el registro de usuario; falla cuando se hace clic en el enlace "confirmar mi cuenta" desde el correo electrónico.

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$

Este error es reproducible cuando me suscribo manualmente a través del servidor web también, por lo que no parece ser un problema de Pepino.

Me gustaría:

  • El usuario puede confirmar con un solo clic su cuenta a través del enlace de este correo electrónico
  • Haga que el usuario permanezca conectado después de confirmar su cuenta

Tengo la configuración:

  • El último código de Devise, de GitHub (3.1.0, ref 041fcf90807df5efded5fdcd53ced80544e7430f)
  • Una clase de User que implemente confirmable
  • Uso del controlador de confirmación ''predeterminado'' (no he definido el mío propio).

He leído estas publicaciones:

Y lo he intentado:

  • Estableciendo config.allow_insecure_tokens_lookup = true en mi inicializador Devise, que arroja un error de ''método desconocido'' al inicio. Además, parece que esto solo se supone que es una solución temporal, por lo que me gustaría evitar su uso.
  • Purgué mi DB y comencé desde cero (para que no haya tokens antiguos)

Actualizar:

Verificando el token de confirmación almacenado en el User después de registrarse. El token de correos electrónicos coincide con el token de DBs. De acuerdo con las publicaciones anteriores, el nuevo comportamiento de Devise dice que no se supone que debe hacerlo, y que en su lugar debe generar un segundo token basado en el token del correo electrónico. Esto es sospechoso Ejecutar User.confirm_by_token(''[EMAIL_CONFIRMATION_TOKEN]'') devuelve un usuario que tiene errores establecidos "@messages = {: confirmation_token => [" is invalid "]}", que parece ser el origen del problema.

Tokens que no coinciden parece ser el corazón del problema; ejecutar el siguiente código en la consola para cambiar manualmente la Confirmación de confirmación del usuario hace que la confirmación tenga éxito:

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

Entonces, ¿por qué está guardando el token de confirmación equivocado en el DB en primer lugar? Estoy usando un controlador de registro personalizado ... ¿tal vez hay algo en él que hace que se establezca incorrectamente?

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


A partir del dispositivo 3.5.2, el token de confirmación ya no se digiere durante el proceso de confirmación. Esto significa que el token en el correo electrónico coincidirá con el token en la base de datos.

Todavía tenía problemas con las confirmaciones después de descubrir esto, pero en mi caso resultó ser un error que introduje cuando find_first_by_auth_conditions . Al corregir el error que introduje en ese método, corregí mis errores con confirmación.


Así que actualizar a Devise 3.1.0 dejó un poco de ''cruft'' en una vista que no había tocado en mucho tiempo.

De acuerdo con esta publicación del blog , debe cambiar su correo de Devise para usar @token lugar del antiguo @resource.confirmation_token .

Encuentre esto en la app/views/<user>/mailer/confirmation_instructions.html.erb y cámbielo a algo como:

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

Esto debería solucionar cualquier problema de confirmación basado en token que estés teniendo. Es probable que también solucione cualquier problema de desbloqueo o restauración de token de contraseña.


Un amigo mío acaba de encontrar esta pregunta y me envió un correo electrónico preguntándome si me había dado cuenta de esto, lo que me recordó que nunca presenté mi propia respuesta, así que aquí va :)

Terminé restableciendo el token y usando send para obtener el token en bruto. Es feo, pero funciona en un golpe para el 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