2016-12-06 6 views
0

ich Setup habe eine moreless einfache soziale Benutzerauthentifizierung auf der devise mit Google, Linkedin, Dropbox und Github.

Die Dropbox Authentifizierung nicht, stattdessen funktioniert gibt es, dass Fehler auf der Callback-URL
(http://localhost:3000/users/auth/dropbox/callback):Rails 4: Benutzerauthentifizierung - NoMethodError

NoMethodError in Users::OmniauthCallbacksController#dropbox 
undefined method `first' for nil:NilClass 

Ausgabe: Benutzermodell (Linie 8)


Mein Code:

Rückrufe Controller:

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController 

    def all 
     user = User.from_omniauth(env['omniauth.auth'], current_user) 
     if user.persisted? 
      sign_in user 
      flash[:notice] = t('devise.omniauth_callbacks.success', :kind => User::SOCIALS[params[:action].to_sym]) 
      if user.sign_in_count == 1 
       redirect_to edit_user_registration_path 
      else 
       redirect_to root_path 
      end 
     else 
      session['devise.user_attributes'] = user.attributes 
      redirect_to new_user_registration_url 
     end 
    end 

    User::SOCIALS.each do |k, _| 
     alias_method k, :all 
    end 

end 

Benutzermodell:

# omniauth Gem 
def self.from_omniauth(auth, current_user) 
    authorization = Authorization.where(:provider => auth.provider, :uid => auth.uid.to_s, 
             :token => auth.credentials.token, 
             :secret => auth.credentials.secret).first_or_initialize 
    authorization.profile_page = auth.info.urls.first.last unless authorization.persisted? 
    if authorization.user.blank? 
     user = current_user.nil? ? User.where('email = ?', auth['info']['email']).first : current_user 
     if user.blank? 
      user = User.new 
      user.skip_confirmation! 
      user.password = Devise.friendly_token[0, 20] 
      user.fetch_details(auth) 
      user.save 
     end 
     authorization.user = user 
     authorization.save 
    end 
    authorization.user 
end 

def fetch_details(auth) 
    self.email = auth.info.email 
    self.username = auth.info.name 
    self.avatar = URI.parse(auth.info.image) 
end 

schätze ich jede Hilfe! Danke im Voraus.

Antwort

1

Um Ihre Frage direkt zu beantworten: Die undefined method "first" for nil::NilClass passiert, weil Sie versuchen, die Methode first auf ein leeres oder Null-Objekt aufzurufen.

Es ist wahrscheinlich in Ihrem Benutzermodell, wo Sie versuchen, einen Benutzer von einem aktuellen Benutzer zu finden.

if authorization.user.blank? user = current_user.nil? ? User.where('email = ?', auth['info']['email']).first : current_user #This will cause the error that you are describing if both the current_user is nil and there is no User whose email is auth['info']['email']

Jetzt gibt es ein paar Dinge falsch mit diesem. Wenn sie versuchen, sich bei Ihrer Anwendung anzumelden, sollte current_user zu diesem Zeitpunkt nicht gesetzt sein.

könnten Sie versuchen, diese

user = User.where(email: auth['info']['email']).first_or_create

an veränderte, die eine neue Instanz des Benutzers erstellen wird, wenn man nicht mit der E-Mail in der Ermächtigung vorhanden ist. Dann können Sie mit

user.persisted? fortzusetzen, die für einen bestehenden Benutzer true zurückgibt, und falsch für eine neue Instanz von Benutzer

+0

ich glaube, das ist das Problem in Zeile 5 des User-Modell ist, da der Fehler blieb nach Ich habe deine Vorschläge aufgenommen. Es scheint für Dropbox irgendwie nicht eine URL zu finden. – jonhue

+0

Also, das gleiche Prinzip gilt. Sie rufen ".first" auf "auth.info.urls" auf, was bedeutet, dass es entweder leer ist oder nicht existiert. Debuggen Sie mit Hilfe von "pry" oder "byebug", um Ihr Programm direkt vor dieser Zeile zu stoppen und zu überprüfen, was die Auth tatsächlich zurückgibt, und formatieren Sie den Code entsprechend. –

Verwandte Themen