[英]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_token
或after_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.