2014-01-10 125 views
3

我用devise來允許用戶在站點內註冊和登錄。我也使用omniauth-facebook允許用戶使用他們的Facebook帳戶登錄。但是,首先使用Facebook電子郵件註冊同一電子郵件的人不能使用他們的Facebook帳戶登錄。我想同時使用Facebook登錄和網站註冊。如何允許用戶使用註冊賬戶和Facebook賬戶登錄?

這是我user.rb

class User < ActiveRecord::Base 

    devise :database_authenticatable, :registerable, 
    :recoverable, :rememberable, :trackable, :validatable, :omniauthable 

    def self.find_for_facebook_oauth(auth, signed_in_resource=nil) 
    user = User.where(:provider => auth.provider, :uid => auth.uid).first 
    unless user 
     user = User.create(name:auth.extra.raw_info.name, 
         provider:auth.provider, 
         uid:auth.uid, 
         email:auth.info.email, 
         password:Devise.friendly_token[0,20] 
         ) 
    end 
    user 
    end 
end 

而且omniauth_callbacks_controller.rb

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController 
    def facebook 
    @user = User.find_for_facebook_oauth(request.env["omniauth.auth"], current_user) 

    if @user.persisted? 
     sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated 
     set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format? 
    else 
     session["devise.facebook_data"] = request.env["omniauth.auth"] 
     redirect_to new_user_registration_url 
    end 
    end 
end 
+0

你想同時使用facebook登錄以及設計(電子郵件/通行證)還是隻有其中一個?我可以基於此回答你的問題 - 謝謝 –

+0

@matrixtheone我想同時使用Facebook登錄和設計註冊。謝謝! – achilleo

回答

0

可以在用戶模型中添加自定義驗證的電子郵件領域像

email_regex = /\A[\w+\-.][email protected][a-z\d\-.]+\.[a-z]+\z/i 
validates :email, :presence =>{:message => "An email address must be entered."}, 
        :format => { :with => email_regex , :message => "The email address is not valid." }, 
        :uniqueness => { :case_sensitive => false, :message => "The email address is already used."} 
+0

這是如何以任何方式解決問題的? – phoet

+0

任何時候當你想要保存用戶記錄的時候,它將會在數據庫中已經存在的電子郵件中進行驗證。 –

1

你可以通過以下方式輕鬆做到這一點:

  1. 創建名爲授權另一個模型的屬性:

    provider:string, uid:string, user_id:integer 
    
  2. 現在,用戶將與授權如下相關:

    class User 
        has_many :authorizations 
        ... 
    end 
    
  3. 每當Facebook登錄時,請與授權模型來查看是否存在記錄。如果不創建它並將其鏈接到用戶模型(通過電子郵件ID搜索)。

  4. 獲取正確的用戶對象並用它登錄。

來源:http://net.tutsplus.com/tutorials/ruby/how-to-use-omniauth-to-authenticate-your-users/

+0

謝謝,我已經根據你的解決方案解決了這個問題。偉大的幫助! – achilleo

0

我問這個問題,只是發現了基於matrixtheone的anwser(真的有很大的幫助),這博客的方式。 http://www.orhancanceylan.com/rails-twitter-and-facebook-authentications-with-omniauth-and-devise/

這是代碼。如果有什麼問題,請把它弄清楚

def facebook 
    omni = request.env["omniauth.auth"] 
    authentication = Authentication.find_by_provider_and_uid(omni['provider'],omni['uid']) 

    if authentication 
    flash[:notice] = "Logged in Successfully" 
    sign_in_and_redirect User.find(authentication.user_id) 
    elsif user = User.find_by(email: omni['extra']['raw_info'].email) 
    user.authentications.create!(provider:omni['provider'], 
         uid:omni['uid']) 
    flash[:notice] = "Authentication for registered user is successful" 
    sign_in_and_redirect user 
    else 
    user = User.new 
    user.password = Devise.friendly_token[0,20] 
    user.email = omni['extra']['raw_info'].email 
    user.authentications.build(provider:omni['provider'], 
         uid:omni['uid']) 
    if user.save 
     flash[:notice] = "Logged in." 
     sign_in_and_redirect User.find(user.id) 
    else 
     session[:omniauth] = omni.except('extra') 
     redirect_to new_user_registration_path 
    end 
    end 
end 
+0

請記住,這種登錄邏輯存在安全問題。你可以用這種方式強化用戶帳戶! – phoet