【问题标题】:Customize reset_password_token for devise in Rails为 Rails 中的设计自定义 reset_password_token
【发布时间】:2019-11-21 16:59:43
【问题描述】:

我想要做的:设置一个邀请流程,当用户邀请新用户时,它会创建一个用户(电子邮件和密码)并向该新用户发送一封欢迎电子邮件,其中包含重置密码的链接。

我的用户模型

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

我的 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)

当我在set_initial_password_reset! 中“提升”到用户模型以分析@token_reset 时,我得到了一个值,但在 InviteController 中该值为 nil,我不明白如何获取该值?

我尝试过在 stackoverflow 上看到的其他方法来实现该过程,例如:

用户模型

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

InviteController

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

但生成的令牌无效。我应该有这样的令牌:http://localhost:3000/users/password/edit?reset_password_token=i8t77fcdsj3PYRymVdEK 但我得到一个更长的令牌。

获取信息我的邮件控制器

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

感谢您的帮助!

【问题讨论】:

    标签: ruby-on-rails authentication devise mailer reset-password


    【解决方案1】:

    所以set_initial_password_reset! 的问题是您没有获得稍后将用于在密码重置过程中识别资源的原始令牌值。

    从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
    

    它将加密生成的令牌保存到用户对象并返回原始值。 然后,该原始值应包含在将用作收件人(用户)的邮件/链接中,同时确认确实是他/她可以重置密码。

    因此,如果我们重新查看您发布的代码示例,控制器将如下所示:

    在模型中:(与设计方法基本相同。唯一的区别是设计方法是私有的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
    

    在控制器中:

    @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
    

    【讨论】:

    • 非常感谢!很好的解释
    • 如果这回答了您的问题,请接受答案。否则,如果还有其他需要澄清的事情,请在 cmets 中告诉我:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-28
    • 2018-05-27
    • 1970-01-01
    • 2011-10-02
    • 2015-05-26
    • 1970-01-01
    相关资源
    最近更新 更多