How to get around password verification in the following OmniAuth login method?

I have a password check for my User model and the create_with_omniauth method to retrieve information from a Facebook user account:

user.rb:

 class User < ActiveRecord::Base attr_accessible :name, :email, :password, :password_confirmation has_secure_password validates :name, presence: true, length: { maximum: 50 } VALID_EMAIL_REGEX = /\A[\w+\-.] +@ [az\d\-.]+\.[az]+\z/i validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false } validates :password, presence: true, length: { minimum: 6 } validates :password_confirmation, presence: true def self.create_with_omniauth(auth) create! do |user| user.provider = auth["provider"] user.uid = auth["uid"] user.name = auth["info"]["name"] user.email = auth["info"]["email"] end end end 

Now when I click link_to "Sign in with Facebook, "auth/facebook" , I get this error:

Verification failed: Password cannot be empty, password cannot be empty, Password is too short (minimum 6 characters), password confirmation cannot be empty

Due to these two lines in the User model:

  validates :password, presence: true, length: { minimum: 6 } validates :password_confirmation, presence: true 

How to get around this check when a user tries to log in using the OmniAuth login method?

+6
source share
3 answers

There are two ways to do this.

1) Just save the random protected generated number in the password field (it’s better because it’s easy, as well as to maintain consistency) I personally applied this method, since users who subscribe to the social site will not log into the system through the site.

2) Or use attr_accesor

  :login_social (will be treated as boolean validates :password, presence: true, length: { minimum: 6 }, :if => !login_social? validates :password_confirmation, presence: true, :if => :login_social? 

Whenever you register through any social site, just make this field correct. I followed the second method and then turned to the first solution as it was better.

Personally, I suggest you go to the first method

+17
source

As @Aayush suggested creating a field for detecting social input, instead of creating your own validation, you can override this development method:

  def password_required? self.social_login? ? false : super end 

in your model e.g. User

+2
source

My solution is to add a simple password for omniauth users and make it impossible to log in with these passwords if Rails detects that they are omniauth users. This simplifies my User model as I can still use has_secure_password and makes the password inappropriate (and impossible to use) if they use social login.

The My User database table has the following:

  • name
  • Email
  • password
  • password_confirmation
  • UID
  • the supplier

sessions_controller.rb

 def create auth = request.env["omniauth.auth"] if auth sign_in_with_auth(auth) else sign_in_with_password end end 

sessions_helper.rb

 def sign_in_with_auth(auth) user = User.find_by(uid: auth['uid']) if user #sign in the user else #create a user with any password. user = User.create! do |user| ... user.password = 'bojanglesicedtea' user.password_confirmation = 'bojanglesicedtea' user.provider = auth['provider'] end #then sign in the user end end def sign_in_with_password user = User.find_by(email: params[:sessions][:email].downcase) if user == user.authenticate(params[:sessions][:password]) && user.provider.nil? #sign in the user #user.provider.nil? will be true only if it is not a social login user else #direct to error notification end end 
+1
source

All Articles