简体   繁体   English

在 Rails 中为 devise 自定义 reset_password_token

[英]Customize reset_password_token for devise in Rails

what I want to do: setup an invite process, when a user invite a new user it creates a user (email and password) and send a welcome email to this new user with a link to reset his password.我想要做什么:设置一个邀请过程,当用户邀请一个新用户时,它会创建一个用户(电子邮件和密码)并向这个新用户发送一个欢迎 email 并带有一个链接来重置他的密码。

My User model我的用户 model

def set_initial_password_reset!
    raw, enc = Devise.token_generator.generate(self.class, :reset_password_token)

      self.reset_password_token   = enc
      self.reset_password_sent_at = Time.now.utc
      save(validate: false)
      @token_reset = raw
end

My InviteController contain我的 InviteController 包含

@user_invitee = User.new(email: invite_params[:email]) do |u|
        u.password = SecureRandom.hex
        # raise
        end
   @user_invitee.skip_confirmation!
   @user_invitee.save
   @user_invitee.set_initial_password_reset!
   create_invite

   if @invite.save!
      InviteMailer.new_user_invite(@invite, edit_password_path(@resource = User.find_by(id: 
      @invite.recipient), reset_password_token: @token_reset)).deliver
          redirect_to trip_trip_form(@trip)

when I "raise" into the User model in set_initial_password_reset!当我在 set_initial_password_reset 中“提升”到用户 model 时set_initial_password_reset! to analyze @token_reset, I have got a value, but in the InviteController that value is nil and I don't understand how to grab this value?分析@token_reset,我得到了一个值,但是在 InviteController 中该值为 nil,我不明白如何获取该值?

I have try other method that I saw on stackoverflow to implement that process like:我尝试了在stackoverflow上看到的其他方法来实现该过程,例如:

User model用户 model

def set_initial_password_reset!
    self.reset_password_token   = Devise.token_generator.generate(self.class, :reset_password_token)
    self.reset_password_sent_at = Time.now.utc
    save(validate: false)
  end

and in InviteController并在InviteController

InviteMailer.new_user_invite(@invite, edit_password_path(@resource = User.find_by(id: @invite.recipient), reset_password_token: @resource.reset_password_token)).deliver

but the token generated was invalid.但生成的令牌无效。 I should have a token like this: http://localhost:3000/users/password/edit?reset_password_token=i8t77fcdsj3PYRymVdEK but I get a much longer token.我应该有这样的令牌: http://localhost:3000/users/password/edit?reset_password_token=i8t77fcdsj3PYRymVdEK但我得到了更长的令牌。

for info my mailer controller有关信息我的邮件 controller

class InviteMailer < ApplicationMailer
  def new_user_invite(invite, edit_password_path)
    @invite = invite # Instance variable => available in view
    @new_user_registration_url = edit_password_path
    mail(to: @invite.email, subject: 'Welcome to Travlr!')
    @trip = Trip.find_by(id: @invite.trip_id)
    @sender = User.find_by(id: @invite.sender)
  end

Thanks for your help!谢谢你的帮助!

so the problem with set_initial_password_reset!所以set_initial_password_reset! is the you don't get the raw token value that will be later used to identify the resource in the password reset process.是您没有获得稍后将用于在密码重置过程中识别资源的原始令牌值。

look at the implementation of reset password token method from devise (below)从devise(下)看reset password token方法的实现

    def set_reset_password_token
      raw, enc = Devise.token_generator.generate(self.class, :reset_password_token)

      self.reset_password_token   = enc
      self.reset_password_sent_at = Time.now.utc
      save(validate: false)
      raw
    end

it saves the encrypted generated token to the user object and returns the raw value.它将加密生成的令牌保存给用户 object 并返回原始值。 This raw value then should be included in the mail/link that is going to be used be the recipient (the user) while confirming that indeed it's he/she who can reset the password.然后,该原始值应包含在将用作收件人(用户)的邮件/链接中,同时确认确实是他/她可以重置密码。

so if we revisit the code samples you've posted the controller would look somewhat like below:因此,如果我们重新访问您发布的代码示例,controller 看起来会如下所示:

in model: (basically same as the devise method. the only difference is that devise method is private afaik)在 model 中:(与 devise 方法基本相同。唯一的区别是 devise 方法是私有 afaik)

def set_initial_password_reset!
  raw, enc   = Devise.token_generator.generate(self.class, :reset_password_token)
  self.reset_password_token = enc
  self.reset_password_sent_at = Time.now.utc
  save(validate: false)
  raw
end

in controller:在 controller 中:

@user_invitee = User.new(email: invite_params[:email]) do |u|
    u.password = SecureRandom.hex
    # raise
end
@user_invitee.skip_confirmation!
@user_invitee.save
token = @user_invitee.set_initial_password_reset!
create_invite

InviteMailer.new_user_invite(@invite, edit_password_path(User.find_by(id: @invite.recipient), reset_password_token: token)).deliver

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM