【问题标题】:devise Rails 5 security extension error using update_with_password使用 update_with_password 设计 Rails 5 安全扩展错误
【发布时间】:2016-08-18 21:58:24
【问题描述】:

here好像也有类似的问题,但是没有人能回答。好像也有点不一样。

我正在从 rails 4.2.4 升级到 Rails 5.0.0.1。 当我尝试在 30 天后运行密码过期时,它会执行更新操作,在第二行出现问题:

def update
  resource.extend(Devise::Models::DatabaseAuthenticatablePatch)
  if resource.update_with_password(resource_params)
    warden.session(scope)['password_expired'] = false
    set_flash_message :notice, :updated
    sign_in scope, resource, :bypass => true
    redirect_to stored_location_for(scope) || :root
  else
    clean_up_passwords(resource)
    respond_with(resource, action: :show)
  end
end

这是运行的模块:

module Devise
  module Models
    module DatabaseAuthenticatablePatch
      def update_with_password(params, *options)

        new_password = params[:password]
        new_password_confirmation = params[:password_confirmation]

        result = if new_password.present? && new_password_confirmation.present?
                   update_attributes(params, *options)
                 else
                   self.assign_attributes(params, *options)
                   self.valid?
                   self.errors.add(:password, new_password.blank? ? :blank : :invalid)
                   self.errors.add(:password_confirmation, new_password_confirmation.blank? ? :blank : :invalid)
                   false
                 end

        clean_up_passwords
        result
      end
    end
  end
end

点击update_attributes(params, *options)时发生错误

然后我得到这个错误。

undefined method `<<' for #<OldPassword::ActiveRecord_AssociationRelation:0x007ffe59a0ffa0>

如果有人能帮我解决这个问题,那就太棒了。

提前谢谢你。

【问题讨论】:

    标签: ruby-on-rails devise ruby-on-rails-5


    【解决方案1】:

    问题是 devise_security_extension gem。 我正在使用 password_archivable 并且在他们的模块中,我需要将 old_password 对象转换为一个数组,以便能够将更改的密码添加到表中。

    我最终创建了一个 password_archivable.rb 并将其放入初始化程序中。

    module Devise
      module Models
        # PasswordArchivable
        module PasswordArchivable
          # validate is the password used in the past
          def password_archive_included?
            unless self.class.deny_old_passwords.is_a? Fixnum
              if self.class.deny_old_passwords.is_a? TrueClass and archive_count > 0
                self.class.deny_old_passwords = archive_count
              else
                self.class.deny_old_passwords = 0
              end
            end
            if self.class.deny_old_passwords > 0 and not self.password.nil?
              old_passwords_including_cur_change = self.old_passwords.order(:id).reverse_order.limit(self.class.deny_old_passwords).to_a
              old_passwords_including_cur_change << OldPassword.new(old_password_params)  # include most recent change in list, but don't save it yet!
              old_passwords_including_cur_change.each do |old_password|
                dummy                    = self.class.new
                dummy.encrypted_password = old_password.encrypted_password
                dummy.password_salt      = old_password.password_salt if dummy.respond_to?(:password_salt)
                return true if dummy.valid_password?(self.password)
              end
            end
            false
          end
        end
      end
    end
    

    这是唯一的问题。

    希望这对其他人有所帮助。

    【讨论】:

    • 很好的解决方案。非常感谢你。很有帮助。
    猜你喜欢
    • 1970-01-01
    • 2018-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-24
    • 2012-05-12
    • 1970-01-01
    • 2016-02-08
    相关资源
    最近更新 更多