3

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

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

现在,我希望重置密码令牌在使用后被清除。因此,当您从旧邮件中关注先前使用的发送链接时,他必须收到“无效令牌”的消息

我怎样才能做到这一点?

提前致谢。

4

4 回答 4

2

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

创建您自己的密码控制器,我选择将其放在控制器/身份验证下

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

于 2014-02-01T10:35:07.813 回答
0

我认为如果您在用户模型或设计使用的模型中执行以下操作,此 hack 应该会更容易。

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

希望这会有所帮助。

于 2014-11-23T08:06:37.927 回答
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_tokenafter_password_reset方法。

于 2013-11-14T06:20:10.307 回答
-1

我通过在应用程序中覆盖 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
于 2013-12-09T07:13:03.863 回答