How to skip has_secure_password validations

后端 未结 3 517
忘掉有多难
忘掉有多难 2020-12-09 03:22

In my app, only admins can create new User records. The user is emailed an activation link where they set their password.

I\'d like to use the has_secure_passord met

相关标签:
3条回答
  • 2020-12-09 04:06

    I decided to do my own custom authentication. The following solution will validate passwords but only when they are being set. This allows admins to create users without adding a password.

    class User < ActiveRecord::Base
      include BCrypt
    
      attr_accessor :password, :password_confirmation
    
      validates :password, length: (6..32), confirmation: true, if: :setting_password?
    
      def password=(password)
        @password = password
        self.password_hash = Password.create(password)
      end
    
      def authenticate(password)
        password.present? && password_hash.present? && Password.new(password_hash) == password
      end
    
    private
    
      def setting_password?
        password || password_confirmation
      end
    
    end
    

    If someone posts an answer that allows me to still use the has_secure_password method, I'll accept it instead.

    0 讨论(0)
  • 2020-12-09 04:15

    Since 4.X versions of rails, has_secure_password takes an option :validations. If you set it to false, it will not run validations.

    The 3.X version of the gem does not support this parameter. However you can backport the activemodel/lib/active_model/secure_password.rb from latest 4.0.XRC code which supports this argument.

    So with that, your code will look like this:

    class User < ActiveRecord::Base
      has_secure_password :validations => false
      ...
    end
    
    0 讨论(0)
  • 2020-12-09 04:24

    There's no way to skip the validation, but it would be easy enough to write your own version of the method that allows you to pass an argument to determine whether or not to validate presence of the password_digest field.

    Just extend ActiveModel the same way they do in the SecurePassword module (via ActiveSupport::Concern) and add your own secure password method.

    i.e.

    module ActiveModel
      module MySecurePassword
        extend ActiveSupport::Concern
    
        module ClassMethods
          def my_has_secure_password(validate_password_digest=true)
            # you custom logic
          end
        end
      end
    end
    
    0 讨论(0)
提交回复
热议问题