7

我正在创建一个基本的 Ruby on Rails 4 项目,该项目允许用户创建帐户、登录等...我使用内置has_secure_password来管理密码。我不希望用户必须输入两次密码(即需要password_confirmation输入表单字段和相应的模型属性)。所以,我正在寻找一种方法来关闭password_confirmation检查/要求。

我发现这个答案提供了一个潜在的解决方案,但原来的问题有足够的不同,我想单独验证它。它建议更新用户模型以添加以下内容:

class User < ActiveRecord::Base

  # ...

  has_secure_password validations: false
  validates :password, presence: true, length: { minimum: 6 }

end

这似乎有效,并允许我的 RSpec 测试通过。我的两部分问题是:

  1. 这种方法是否有任何负面后果或安全问题?
  2. password_confirmation是否有其他更安全或更符合“红宝石之路”的关闭方法?
4

3 回答 3

12

ActiveModel::SecurePassword有一个 options 参数,您可以指定不执行验证。

has_secure_password validations: false

然后只需确保您手动对密码字段执行验证。

validates_presence_of :password, on: :create

可选地,唯一缺少的另一件事是如果 password_digest 以某种方式为空白,则引发错误。我不知道这怎么可能发生。

before_create { raise "Password digest missing on new record" if password_digest.blank? }

在我看来,这似乎尽可能干净地解决了这个问题。

于 2014-01-15T18:34:58.067 回答
2

如果您查看ActiveModel::SecurePassword,您将看到 has_secure_password 创建的验证。

if options.fetch(:validations, true)
      validates_confirmation_of :password, if: :should_confirm_password?
      validates_presence_of     :password, on: :create
      validates_presence_of     :password_confirmation, if: :should_confirm_password?

      before_create { raise "Password digest missing on new record" if password_digest.blank? }
end

通过禁用验证,您还可以阻止对 field 的检查:password_digest,这不是什么大不了的事,但仍然不理想。

我认为更好的选择是覆盖默认方法,should_confirm_password?

# If password_confirmation is passed, business as usual.
# If not, don't run the validations
def should_confirm_password?
    password_confirmation.present? || false
end
于 2013-11-01T18:13:01.883 回答
0

对于 Rails 6,AFAICT(没有检查其他版本),您根本不将password_confirmation属性传递给您的模型。默认情况下不需要。

https://github.com/rails/rails/blob/master/activemodel/lib/active_model/validations/confirmation.rb#L75

于 2019-10-14T11:48:48.877 回答