Rails devise重置密码令牌未被清除。

3
我正在使用devise gem。当用户点击忘记密码链接时,Devise会在邮件中发送重置密码令牌。用户跟随链接并通过输入新密码和确认新密码来重置密码。
当我再次跟随相同的邮件链接时,它仍然允许用户以与上述相同的方式重置密码。
现在,我希望一旦使用重置密码令牌,就将其清除。这样,当您从旧邮件中跟随先前使用的发送链接时,他必须收到“无效令牌”的消息。
我该如何做到这一点?
谢谢!

你正在使用哪个版本的Rails和devise? - Arihant Godha
Rails 3.2.13 Devise 3.1.0 - Ketan Ghumatkar
4个回答

2
比之前提出的方案更加简单且安全的解决方案:
创建自己的密码控制器,我选择将其放置在controllers/auth下。
controllers/auth/passwords_controller.rb
class Auth::PasswordsController < Devise::PasswordsController

  def update
    super do |resource|
      if resource.reset_password_token_changed? and resource.reset_password_token_was.nil?
        resource.reset_password_token = nil 
      end
    end
  end

end

这样做可以解决许多与Papertrail相关的问题,而且还能减少对数据库的访问次数。

0

我认为如果您在用户模型或Devise使用的模型中执行以下操作,这个黑客应该会更容易。

class YourModel < ActiveRecord::Base
  ...
     def after_password_reset
          self.clear_reset_password_token if not (self.reset_password_token.nil? and self.reset_password_sent_at.nil?)
     end
end

我建议不要使用您的控制器执行业务操作。after_password_reset密码用于在devise中清除reset_password令牌后调用。以下是参考链接: https://github.com/plataformatec/devise/blob/master/lib/devise/models/recoverable.rb#L39

希望这可以帮到您。


“after_password_reset” 已在 devise 4.2.0(2016-07-01)中删除。没有给出原因或替代方法 https://github.com/heartcombo/devise/blob/main/CHANGELOG.md#420---2016-07-01 - jox

0
您可以尝试以下任一方法:
 # reset_password_within = 1.day and reset_password_sent_at = today
reset_password_period_valid?   # returns true

# reset_password_within = 5.days and reset_password_sent_at = 4.days.ago
reset_password_period_valid?   # returns true

# reset_password_within = 5.days and reset_password_sent_at = 5.days.ago
reset_password_period_valid?   # returns false

# reset_password_within = 0.days
reset_password_period_valid?   # will always return false

或者您可以通过调用实例方法,如clear reset password token或通过调用clear_reset_password_tokenafter_password_reset方法等方式。


1
如何在哪里使用reset_password_period_valid方法来显示“令牌无效”消息,如果令牌有效,则用户将继续输入新密码。您能否清晰地解释一下?我需要覆盖密码控制器吗? - Ketan Ghumatkar

-1

我通过在应用程序中覆盖Devise :: PasswordsController来实现了上述功能。

Devise在PasswordController#edit操作中处理重置密码。

在编辑时,我检查重置密码令牌是否有效。如果有效,我允许用户重置密码,否则将用户重定向到登录页面,并显示“密码令牌无效”消息。

适用于Devise 3.0

class Users::PasswordsController < Devise::PasswordsController
  def edit
    self.resource = resource_class.find_or_initialize_with_error_by(:reset_password_token,       params[:reset_password_token])
    if !resource.errors.empty?
      flash[:alert] = "Password token is invalid"
      redirect_to new_session_path(resource_name)
    end 
  end
end

针对 devise 3.1

class Users::PasswordsController < Devise::PasswordsController
  def edit
    original_token       = params[:reset_password_token]
    reset_password_token = Devise.token_generator.digest(self, :reset_password_token, original_token)
    self.resource = resource_class.find_or_initialize_with_error_by(:reset_password_token, reset_password_token)
    if !resource.errors.empty?
      flash[:alert] = "Password token is invalid"
      redirect_to new_session_path(resource_name)
    end
  end
end

您可以覆盖after_password_reset方法来在您的模型上执行此操作。您不需要为此生成控制器。 - Rubyrider

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接