【问题标题】:How to generate reset password token如何生成重置密码令牌
【发布时间】:2026-01-05 23:10:01
【问题描述】:

我正在使用 devise gem 进行身份验证。

在我的应用程序中,管理员将创建用户,所以我想要管理员创建用户时用户的重置密码链接。

这是我的行动:-

def create
   @user = User.new(user_params)
   @user.password = '123123123'
   @user.password_confirmation = '123123123'
   if @user.save
         @user.update_attributes(:confirmation_token => nil,:confirmed_at => Time.now,:reset_password_token => (0...16).map{(65+rand(26)).chr}.join,:reset_password_sent_at => Time.now)
       UserMailer.user_link(@user).deliver
       redirect_to users_path
     else
    render :action => "new"
   end
end

这是我重置用户密码的链接

但是当我打开链接并更新密码时,我得到的重置密码令牌无效。

【问题讨论】:

    标签: ruby-on-rails devise


    【解决方案1】:

    如果您使用的是设计,为什么要创建自己的密码重置令牌? 设计有一个功能。 http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Recoverable

    如果您想知道当用户想要重置密码时,devise 会这样做:

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

    self 在这里是一个用户对象

    在您的 URL 中,您必须将 raw 作为 reset_password_token 参数传递

    【讨论】:

      【解决方案2】:

      您可以使用以下命令生成令牌:

      Devise.token_generator.generate(User, :reset_password_token)
      

      虽然这本身只是一个无用的字符串。如果您确实想在链接中使用它来重置密码,则需要将其附加到用户:

      user.reset_password_token = hashed_token
      user.reset_password_sent_at = Time.now.utc
      

      然后向他们发送包含链接的电子邮件:

      edit_password_url(@user, reset_password_token: @token)
      

      【讨论】:

        【解决方案3】:

        您可以为此使用user.send_reset_password_instructions

        【讨论】:

        • 我应该在哪里使用这个?
        • 我无法设计使用正确的邮件...我只需要生成令牌
        【解决方案4】:

        如果您不希望它发送指令,只需设置并存储令牌即可调用设计recoverable关注set_reset_password_token中的私有方法。

        您可以通过 user.send(:set_reset_password_token) 之类的操作来做到这一点。

        【讨论】:

          【解决方案5】:

          要使用 Devise 获取重置密码的 url,我使用了这个 sn-p 代码:

          user = User.find(id)
          raw, enc = Devise.token_generator.generate(User, :reset_password_token)
          user.update_columns(reset_password_token: enc, reset_password_sent_at: Time.current)
          puts Rails.application.routes.url_helpers.edit_user_password_url(reset_password_token: raw, host: 'localhost:3000')
          

          【讨论】:

            【解决方案6】:

            扩展@Rails Fan's answer。在Recoverable模块中处理密码重置的具体方法是受保护的方法set_reset_password_token

            您可以通过以下代码访问它,它会直接返回令牌。

            ## your model.send(:set_reset_password_token)
            user.send(:set_reset_password_token)
            

            【讨论】: