2016-07-01 13 views
8

Ich weiß, dass dies oft gefragt wurde, aber die Antworten sind nie vollständig akzeptabel für mich.Schienen 5, Devise, Omniauth, Twitter

Also ich bin Ryan Bates' Railscast über dieses Thema, und mischen, dass mit der offiziellen Devise Omniauth guide (die auf FB basiert), aber ich bin gerade nicht bekommen es zu arbeiten, wie ich es erwarte, also würde ich etwas Hilfe lieben.

Ich habe ein Users::OmniauthCallbacksController die wie folgt aussieht:

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController 
    def all 
    @user = User.from_omniauth(request.env["omniauth.auth"]) 

    if @user.persisted? 
     sign_in_and_redirect root_path, :event => :authentication #this will throw if @user is not activated 
     set_flash_message(:notice, :success, :kind => "Twitter") if is_navigational_format? 
    else 
     session["devise.twitter_data"] = request.env["omniauth.auth"].except("extra") 
     flash[:notice] = flash[:notice].to_a.concat resource.errors.full_messages 
     redirect_to new_user_registration_url 
    end 
    end 

    alias_method :twitter, :all 

    def failure 
    redirect_to root_path 
    end 
end 

Dann auf Ich habe auch zwei Methoden meinen User.rb

def self.from_omniauth(auth) 
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user| 
     user.update(
     email: auth.info.email, 
     password: Devise.friendly_token[0,20], 
     username: auth.info.nickname, 
     remote_avatar_url: auth.info.image, 
     token: auth.credentials.token, 
     secret: auth.credentials.secret 
    ) 
    end 
    end 

    def self.new_with_session(params, session) 
    super.tap do |user| 
     if data = session["devise.twitter_data"] 
     # user.attributes = params 
     user.update(
      email: params[:email], 
      password: Devise.friendly_token[0,20], 
      username: data["info"]["nickname"], 
      remote_avatar_url: data["info"]["image"], 
      token: data["credentials"]["token"], 
      secret: data["credentials"]["secret"] 
     ) 
     end 
    end 
    end 

ich in eine Vielzahl von Problemen führen. Am unmittelbarsten ist, weil ich das Passwort einstelle, der Benutzer das Passwort nicht kennt, wenn er sich anzumelden versucht (und ich mich nicht automatisch bei der Bestätigung anmelde).

Aber wenn ich das Passwort nicht festlege, fordert es sie nicht auf, das Passwort zu setzen ... also ist das auch irgendwie komisch.

Das sind meine devise Einstellungen auf meinem User Modell:

devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable, :validatable, 
     :confirmable, :omniauthable, :omniauth_providers => [:twitter] 

    validates :username, 
    presence: true, 
    uniqueness: { 
     case_sensitive: false 
    } 

    validate :validate_username 

    def validate_username 
    if User.where(email: username).exists? 
     errors.add(:username, :invalid) 
    end 
    end 

Also meine Frage ist, wenn jemand über Twitter anmeldet, haben sie ein Passwort eingeben müssen? Ich sende sie automatisch an die registration/new.html.erb, da Twitter keinen E-Mail-Wert zurückgibt. Aber ich versuche, den Prozess erst in Gang zu bringen, bevor ich ihn optimiere.

Wie gehe ich mit dem Passwortproblem um?

Edit 1

Für mehr Klarheit, werde ich mit diesem password_required Thema befassen muß, unabhängig von dem OAuth-Anbieter.

Wie überschreibe ich diese Anforderung für alle OAuth-Anbieter?

Antwort

5

Sie the following method zum User Klasse hinzufügen sollte:

def password_required? 
    (provider.blank? || uid.blank?) && super 
end 

Da Twitter des Benutzers E-Mail nicht zurückgibt, können Sie auch auf tweak that email validation wollen, aber der Benutzer registration/new.html.erb Umleitung wie Sie bereits tun scheint, wie die richtige Herangehensweise an mich.