web-dev-qa-db-fra.com

Rails Devise: définir le jeton de réinitialisation du mot de passe et rediriger l'utilisateur

Dans mon application pour un certain cas d'utilisation, je crée un nouvel utilisateur (définissez le mot de passe par programme) et je leur envoie un e-mail de confirmation.

Je voudrais qu'ils puissent changer leur mot de passe immédiatement après avoir confirmé (sans avoir à entrer celui généré par le système que je ne veux pas leur envoyer)

En effet je voudrais
1) Le système crée un nouveau compte d'utilisateur avec le mot de passe généré.
2) Le système envoie un e-mail de confirmation.
3) L'utilisateur clique sur la confirmation et est redirigé pour entrer son mot de passe (envoyez-le effectivement à une URL comme ci-dessous)

<a href="http://localhost:3000/users/password/edit?reset_password_token=v5Q3oQGbsyqAUUxyqLtb">Change my password</a>

Toute aide/pointeurs serait formidable.

42
patrickdavey

Un moyen simple d'avoir une seule étape pour les utilisateurs pour confirmer l'adresse e-mail et définir le mot de passe initial en utilisant le lien que vous avez proposé ...

Envoyez un e-mail généré par votre application, y compris un reset_password_token, et envisagez la possession par l'utilisateur de ce jeton pour confirmer la validité de cette adresse e-mail.

Dans le code de génération de compte système, en supposant que le modèle utilisateur est configuré avec: récupérable et: modules de base de données_authenticatable Devise ...

acct = User.new
acct.password = User.reset_password_token #won't actually be used...  
acct.reset_password_token = User.reset_password_token 
acct.email = "[email protected]" #assuming users will identify themselves with this field
#set other acct fields you may need
acct.save

Rendre la vue de réinitialisation du mot de passe plus claire pour les utilisateurs lors de la définition du mot de passe initial.

vues/devise/mots de passe/edit.html.erb

...
<%= "true" == params[:initial] ? "Set your password" : "Reset your password" %>
...  

Courriel généré

Hi <%= @user.name %>
An account has been generated for you.
Please visit www.oursite.com/users/password/edit?initial=true&reset_password_token=<%= @user.reset_password_token %> to set your password.

Pas besoin d'inclure: un module Devise confirmable dans votre modèle d'utilisateur, car les comptes créés par votre application ne seront pas accessibles sans le reset_password_token dans l'e-mail.

Devise gérera la soumission et effacera le champ reset_password_token.

Voir devise_gem_folder/lib/devise/models/recoverable.rb et database_authenticatable.rb pour plus de détails sur reset_password_token méthode et amis.

Si vous souhaitez utiliser Devise :confirmable module plutôt que cette approche, voir Devise wiki page .

43

Dans Rails 4.1, la modification suivante de la réponse d'Anatortoise House fonctionne:

user = User.new
user.password = SecureRandom.hex #some random unguessable string
raw_token, hashed_token = Devise.token_generator.generate(User, :reset_password_token)
user.reset_password_token = hashed_token
user.reset_password_sent_at = Time.now.utc
user.email = '[email protected]'
user.save!
# Use a mailer you've written, such as:
AccountMailer.set_password_notice(user, raw_token).deliver

La vue e-mail a ce lien:

www.oursite.com/users/password/edit?initial=true&reset_password_token=<%= @raw_token %>
30
ClaytonC

Tu peux appeler

user.send(:set_reset_password_token)

Ce n'est peut-être pas stable, car c'est une méthode protégée, mais cela peut fonctionner pour votre cas. Couvrez-le simplement avec un test.

(testé sur Devise v. 3.4)

2
Sergii Mostovyi

Voici mon extrait d'extrait de mailer

class Devise::MailerPreview < ActionMailer::Preview
  def reset_password_instructions
    user = User.last
    token = user.send(:set_reset_password_token)
    Devise::Mailer.reset_password_instructions(user, token)
  end
end
2
woto