繁体   English   中英

Rails设计重置密码令牌不清楚

[英]Rails devise reset password token doesn't get clear

我正在使用devise gem。 当用户单击“忘记密码”链接时,设计发送邮件中的重置密码令牌。 用户点击链接并通过输入新密码并确认新密码来重置密码。

当我再次点击相同的邮件链接时,它再次允许用户以与上述相同的方式重设密码。

现在,我希望重置密码令牌一旦使用就清除。 这样,当您遵循旧邮件中先前使用的发送链接时,他必须收到消息“无效令牌”

我怎样才能做到这一点?

提前致谢。

比建议的解决方案更简单,更安全:

创建您自己的密码控制器,我选择将其放置在controllers / auth下

控制器/ 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的许多问题,并且无论如何节省了对数据库的一种访问

您可以尝试以下任一方法

 # 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_tokenafter_password_reset方法。

我认为,如果您在用户模型或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密码用于调用clear_reset_password令牌。 这是参考: https : //github.com/plataformatec/devise/blob/master/lib/devise/models/recoverable.rb#L39

希望这会有所帮助。

我已经通过重写应用程序中的Devise :: PasswordsController达到了上述目的。

在PasswordController#edit操作上设计句柄重置密码。

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

对于设计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

对于设计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

暂无
暂无

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

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