我正在使用设计宝石。当用户单击忘记密码链接时,设计在邮件中发送重置密码令牌。用户点击链接并通过输入新密码并确认新密码来重置密码。
当我再次点击相同的邮件链接时,它再次允许用户以与上述相同的方式重置密码。
现在,我希望重置密码令牌在使用后被清除。因此,当您从旧邮件中关注先前使用的发送链接时,他必须收到“无效令牌”的消息
我怎样才能做到这一点?
提前致谢。
我正在使用设计宝石。当用户单击忘记密码链接时,设计在邮件中发送重置密码令牌。用户点击链接并通过输入新密码并确认新密码来重置密码。
当我再次点击相同的邮件链接时,它再次允许用户以与上述相同的方式重置密码。
现在,我希望重置密码令牌在使用后被清除。因此,当您从旧邮件中关注先前使用的发送链接时,他必须收到“无效令牌”的消息
我怎样才能做到这一点?
提前致谢。
比建议的更简单、更安全的解决方案:
创建您自己的密码控制器,我选择将其放在控制器/身份验证下
控制器/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 的许多问题,并且无论如何保存对数据库的访问
我认为如果您在用户模型或设计使用的模型中执行以下操作,此 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
希望这会有所帮助。
您可以尝试以下任一方法
# 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
或after_password_reset
方法。
我通过在应用程序中覆盖 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