如果用户连续请求2个密码重置链接,则只有最新的链接有效。
如果用户点击旧版本,则不会立即通知他们该令牌无效。要求他们两次输入新密码。只有在提交提交时,他们才会被告知令牌无效。
是否有更改此行为的标准方法,因此会立即通知用户他们使用了错误的链接?
答案 0 :(得分:3)
我有点惊讶地发现这是标准行为 - 感谢你提出来!我可能会使用一个继承自Devise::PasswordsController
的自定义控制器,只是覆盖:edit
。问题是我们正在使用抽象用户(因为此时没有用户实际验证过),因此我们无法针对数据库中的特定令牌进行检查,我们必须检查给定的令牌是否存在。 / p>
class PasswordsController < Devise::PasswordsController
before_filter :validate_reset_password_token, only: :edit
private
def validate_reset_password_token
recoverable = resource_class.find_by_reset_password_token(params[:reset_password_token])
redirect_to root_path unless (recoverable && recoverable.reset_password_period_valid?)
end
end
除非存在传递令牌的用户,否则这将重定向。您可以根据需要处理重定向/错误显示。
最后,在您的路线文件中,更改设计用于密码的控制器:
devise_for :users, :controllers => { passwords: "passwords" }
注意事项:
reset_password_by_token
中的重置标记来定位模型实例)顺便说一句,没有办法告诉他们他们使用了错误的链接,他们应该点击另一个,因为首先无法正确识别它们,因此无法知道它们已生成另一个有效令牌。
答案 1 :(得分:0)
此问题还有另一种安全解决方案;
class User::PasswordsController < Devise::PasswordsController
def update
super do |resource|
# Jump to super code
next unless resource.errors.any?
token_errors = resource.errors.details[:reset_password_token]
expired_error = token_errors.select { |detail| detail[:error] == :expired }
# Jump to super code
next unless expired_error.present?
message = resource.errors.full_messages_for(:reset_password_token).join(',')
return redirect_to new_user_password_path, alert: message
end
end
end