Utilisation de Rails 4 et de Devise 3.1.0 sur mon application Web. J'ai écrit un test de concombre pour tester l'inscription de l'utilisateur; il échoue lorsque vous cliquez sur le lien "confirmer mon compte" à partir de l'e-mail.
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$
Cette erreur est reproductible lorsque je m'inscris manuellement via le serveur Web également, de sorte que cela ne semble pas être un problème lié au concombre.
J'aimerais:
J'ai mis en place:
User
qui implémente confirmable
J'ai lu ces posts:
Et ont essayé:
config.allow_insecure_tokens_lookup = true
dans mon initialiseur Devise, qui génère une erreur de "méthode inconnue" au démarrage. De plus, il semble que cela ne soit supposé être qu'une solution temporaire, je voudrais donc éviter de l'utiliser.Mettre à jour:
Vérification du jeton de confirmation stocké dans la variable User
après l’enregistrement. Le jeton de courrier électronique correspond au jeton de base de données. Selon les articles ci-dessus, le nouveau comportement de Devise indique qu'il n'est pas censé le faire, mais qu'il devrait plutôt générer un deuxième jeton basé sur le jeton de l'e-mail. Ceci est suspect.} _ La fonction User.confirm_by_token('[EMAIL_CONFIRMATION_TOKEN]')
renvoie un utilisateur qui a des erreurs, définissez "@ messages = =: confirmation_token => [" n'est pas valide "]}", qui semble être la source du problème.
Le désaccord des jetons semble être au cœur du problème; L'exécution du code suivant dans la console pour modifier manuellement le code de confirmation de l'utilisateur entraîne la 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
Alors, pourquoi enregistre-t-il le mauvais jeton de confirmation dans la base de données? J'utilise un contrôleur d'enregistrement personnalisé ... peut-être qu'il contient quelque chose qui le rend incorrect?
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
La mise à niveau vers Devise 3.1.0 a donc laissé un peu de crédibilité dans une vue que je n'avais pas touchée depuis un moment.
Selon cet article de blog , vous devez changer votre logiciel de messagerie Devise pour utiliser @token
au lieu de l'ancien @resource.confirmation_token
.
Trouvez ceci dans app/views/<user>/mailer/confirmation_instructions.html.erb
et changez-le en quelque chose comme:
<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>
Cela devrait résoudre les problèmes de confirmation liés aux jetons que vous rencontrez. Cela corrigera probablement également les problèmes de jeton de mot de passe de déverrouillage ou de réinitialisation.
À partir de la version 3.5.2, le jeton de confirmation n'est plus digéré pendant le processus de confirmation. Cela signifie que le jeton contenu dans l'e-mail correspondra à celui de la base de données.
J'avais toujours des problèmes avec les confirmations après avoir découvert cela, mais dans mon cas, c'est un bogue que j'ai introduit lorsque j'ai surchargé find_first_by_auth_conditions
. En corrigeant le bogue que j'ai introduit dans cette méthode, j'ai corrigé mes erreurs avec confirmation.
Un ami à moi vient de trouver cette question et m'a envoyé un e-mail me demandant si j'avais trouvé cette information, ce qui m'a rappelé que je n'avais jamais soumis ma propre réponse, alors voilà :)
J'ai fini par réinitialiser le jeton et utiliser send
pour obtenir le jeton brut. C'est moche, mais ça marche dans un punch pour 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