Ruby on rails RubyonRails密码验证

Ruby on rails RubyonRails密码验证,ruby-on-rails,validation,Ruby On Rails,Validation,因此,我有一些有趣的密码验证要求: 当用户注册时,我希望他们必须输入密码并确认,并且介于6..40之间(100%正常工作) 当用户更新其配置文件时,应用相同的验证规则(使其100%正常工作) 当管理员添加用户时,他们只需输入一次密码,密码应经过验证(不起作用) 当管理员编辑用户且密码字段为空时,不应更新密码,如果他们键入了什么,则应验证密码。(部分工作) 我唯一不能涵盖的情况是管理员添加用户时,该用户未经验证,以及管理员编辑用户(并键入密码)时,该用户未经验证 :force_submit是

因此,我有一些有趣的密码验证要求:

  • 当用户注册时,我希望他们必须输入密码并确认,并且介于
    6..40
    之间(100%正常工作)

  • 当用户更新其配置文件时,应用相同的验证规则(使其100%正常工作)

  • 当管理员添加用户时,他们只需输入一次密码,密码应经过验证(不起作用)

  • 当管理员编辑用户且密码字段为空时,不应更新密码,如果他们键入了什么,则应验证密码。(部分工作)

我唯一不能涵盖的情况是管理员添加用户时,该用户未经验证,以及管理员编辑用户(并键入密码)时,该用户未经验证

:force_submit
是从管理员表单传入的,因此密码不会被验证。(因此,更新空密码的情况有效)


有什么想法/魔术吗?

下面的内容似乎满足了我的要求……实际上我现在需要所有用户的确认。。(它使视图更清晰)。但在更新中,我允许空白

  validates :password, :presence => true,
                       :confirmation => true,
                       :length => {:within => 6..40},
                       :on => :create
  validates :password, :confirmation => true,
                       :length => {:within => 6..40},
                       :allow_blank => true,
                       :on => :update

这适用于更新操作时的空白密码:

validates :password, :presence => true, :on => :update,
 :if => lambda{ !password.nil? }

validates :password,
  :confirmation => true,
  :length => { :minimum => 6},
  :if => lambda{ new_record? || !password.nil? }
另一种变体

validates_presence_of :password_digest

validates_length_of :password, minimum: 6, if: Proc.new { |user| user.password.present? }

基于公认的答案,下面是我在Rails项目中使用的代码。(注意:我们使用来处理用户身份验证和创建新用户。)


就目前情况而言,这个答案很弱。你能解释一下这个答案与其他答案不同或更可取的原因吗?我不明白这将如何解决问题的第三个要求。这个要求似乎要求管理员可以将密码字段留空,但编辑另一个字段并保存用户,而不更改密码。上面的代码似乎允许保存用户对象,但会将密码更改为空?上面的代码无法解决要求#3,但其行为也与您描述的方式不同。此代码所做的只是允许您在不提供密码的情况下更新用户(例如更改其姓名、地址或电子邮件等)。虽然这是可以做到的,但老实说,我不认为要求#3是一个好主意-密码确认是一个非常简单且有效的安全网。完美!我想在密码格式中再添加一个:不能包含3个或更多的重复或连续字符(例如123、abc、zzz、555)。我该怎么做?@Arif老实说,从安全角度来看,我的实际建议是只使用一个健壮的库,比如检查密码熵,而不是自己尝试重新实现一个安全检查。但是,如果你有一个特定的、定义良好的“安全要求”列表(例如,如果一个客户坚持您的密码策略符合他们的任意标准),那么我的建议是编写一个脚本来显式地处理每个场景。(不要忽略添加单元测试!)
validates_presence_of :password_digest

validates_length_of :password, minimum: 6, if: Proc.new { |user| user.password.present? }
PASSWORD_FORMAT = /\A
  (?=.{8,})          # Must contain 8 or more characters
  (?=.*\d)           # Must contain a digit
  (?=.*[a-z])        # Must contain a lower case character
  (?=.*[A-Z])        # Must contain an upper case character
  (?=.*[[:^alnum:]]) # Must contain a symbol
/x

validates :password, 
  presence: true, 
  length: { in: Devise.password_length }, 
  format: { with: PASSWORD_FORMAT }, 
  confirmation: true, 
  on: :create 

validates :password, 
  allow_nil: true, 
  length: { in: Devise.password_length }, 
  format: { with: PASSWORD_FORMAT }, 
  confirmation: true, 
  on: :update