2012-11-02 19 views
6

Mam poprawności hasła do mojego User modelu oraz sposób create_with_omniauth aby uzyskać informacje od użytkownika konta na Facebooku:Jak pominąć sprawdzanie poprawności hasła w poniższej metodzie logowania OmniAuth?

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+\-.][email protected][a-z\d\-.]+\.[a-z]+\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 

Teraz po kliknięciu link_to "Sign in with Facebook, "auth/facebook" otrzymuję ten błąd:

Validation failed: Password can't be blank, Password can't be blank, Password is too short (minimum is 6 characters), Password confirmation can't be blank

z tego powodu dwie linie w modelu User:

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

Jak pominąć to sprawdzanie, gdy użytkownik próbuje zalogować się przy użyciu metody logowania OmniAuth?

Odpowiedz

17

Można to zrobić na dwa sposoby.

1) Wystarczy zapisać losowo bezpieczny wygenerowany numer w polu hasła (lepiej, ponieważ jest to łatwe, a także zachować spójność) osobiście Zastosowałem tę metodę, ponieważ użytkownicy, którzy podpisali się za pośrednictwem witryny społecznościowej, nie logują się za pośrednictwem witryny Zaloguj Się.

2) Lub użyć 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? 

Ilekroć zalogowaniu za pośrednictwem dowolnej strony społecznej po prostu zrobić to pole prawda. Postępowałem zgodnie z drugą metodą, a następnie zwróciłem się do pierwszego rozwiązania, ponieważ było lepiej.

Osobiście proponuję udać się do pierwszej metody

+0

Hej dzięki za sugestie! Przepraszam, jestem początkującym Railsiem. Czy możesz podać przykład kodu, który wygeneruje losowe hasło, gdy użytkownik kliknie znak Facebooka? – alexchenco

+0

self.password = self.password_confirmation = SecureRandom.urlsafe_base64 (n = 6) –

+0

Dzięki! Czy powinno to iść w metodzie 'self.create_with_omniauth'? Czy nie powinno to być "user.password"? – alexchenco

1

Moje rozwiązanie do tego celu jest dodanie prostego hasła do omniauth użytkowników i uniemożliwiać zalogowanie się z tymi hasłami jeśli Szyny wykryje, że są one omniauth użytkowników. Upraszcza to mój model użytkownika, ponieważ wciąż mogę używać has_secure_password i sprawia, że ​​hasło jest nieistotne (i niemożliwe do użycia), jeśli używa on logowania społecznościowego.

moim tabeli bazy danych Użytkownik ma następujący:

  • nazwa
  • email
  • hasło
  • password_confirmation
  • uid
  • dostawcy

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 
+0

tylko dla kogoś, kto może tego potrzebować, jeśli używasz has_secure_password i masz sprawdzanie poprawności hasła, musisz podać hasło. To zadziałało dla mnie, gdy korzystałem z gemu omariauth google oauth2. –

2

Jak @Aayush zaproponował, aby stworzyć pole do wykrywania logowanie społecznego, wówczas zamiast tworzenia własnego walidacji można zastąpić tę metodę opracować:

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

w swoim modelu e.g User

Powiązane problemy