2016-07-01 30 views
8

So che questo è stato chiesto molte volte, ma le risposte non sono mai completamente accettabili per me.Rails 5, Devise, Omniauth, Twitter

Quindi sto seguendo lo Ryan Bates' Railscast su questo argomento e lo sto miscelando con lo Devise Omniauth guide ufficiale (che si basa su FB), ma non riesco a farlo funzionare come mi aspetto, quindi mi piacerebbe un po 'di aiuto.

ho un Users::OmniauthCallbacksController che assomiglia a questo:

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 

Poi Ho anche due metodi sul mio 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 

mi imbatto in una varietà di problemi. Il più immediato è perché sto impostando la password, l'utente non conosce la password quando provano ad accedere (e non li firmo automaticamente alla conferma).

Ma se non imposto la password, non chiede loro di impostare la password ... quindi anche questo è un po 'strano.

Queste sono le mie impostazioni testamentaria sul mio modello User:

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 

Quindi la mia domanda è questa, quando qualcuno si iscrive via Twitter, hanno bisogno di inserire una password? Li invio automaticamente allo registration/new.html.erb perché Twitter non restituisce un valore email. Ma sto cercando di far funzionare il processo prima, prima di ottimizzarlo.

Come posso risolvere il problema con la password?

Modifica 1

Per maggiore chiarezza, dovrò affrontare questo problema password_required indipendentemente dal fornitore OAuth.

Quindi, come sovrascrivo quel requisito per tutti i provider OAuth?

risposta

5

Si dovrebbe aggiungere the following method alla classe User:

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

Dato che Twitter non ritorna e-mail dell'utente, si consiglia inoltre di tweak that email validation, ma reindirizzare l'utente a registration/new.html.erb come si sta già facendo sembra l'approccio corretto per me.

Problemi correlati