2016-07-01 18 views
8

Tôi biết điều này đã được hỏi nhiều lần, nhưng câu trả lời không bao giờ được chấp nhận hoàn toàn đối với tôi.Rails 5, Devise, Omniauth, Twitter

Vì vậy, tôi đang theo dõi Ryan Bates' Railscast về chủ đề này và trộn với chính thức Devise Omniauth guide (dựa trên FB), nhưng tôi không làm cho nó hoạt động như tôi mong đợi, vì vậy tôi rất muốn được trợ giúp.

Tôi có một Users::OmniauthCallbacksController trông như thế này:

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 

Sau đó, tôi cũng có hai phương pháp trên tôi 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 

tôi chạy vào một loạt các vấn đề. Ngay lập tức nhất là vì tôi thiết lập mật khẩu, người dùng không biết mật khẩu khi họ cố đăng nhập (và tôi không tự động đăng nhập khi xác nhận).

Nhưng nếu tôi không đặt mật khẩu, nó không yêu cầu họ đặt mật khẩu ... vì vậy cũng khá kỳ lạ.

Đây là những thiết lập devise tôi trên mô hình User tôi:

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 

Vì vậy, câu hỏi của tôi là thế này, khi ai đó đăng ký thông qua Twitter, họ cần phải nhập mật khẩu? Tôi tự động gửi chúng đến registration/new.html.erb vì Twitter không trả lại giá trị email. Nhưng tôi đang cố gắng để có được quá trình làm việc đầu tiên, trước khi tối ưu hóa nó.

Làm cách nào để giải quyết vấn đề về mật khẩu?

Sửa 1

Để rõ ràng hơn, tôi sẽ phải đối phó với vấn đề password_required này không phụ thuộc vào nhà cung cấp OAuth.

Vậy làm cách nào để ghi đè yêu cầu đó cho tất cả các nhà cung cấp OAuth?

Trả lời

5

Bạn nên thêm the following method đến lớp User:

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

Kể từ khi Twitter không trả lại email của người dùng, bạn cũng có thể muốn tweak that email validation, nhưng chuyển hướng người dùng đến registration/new.html.erb như bạn đã làm có vẻ như cách tiếp cận chính xác với tôi.

Các vấn đề liên quan