2014-01-21 78 views
20

我花了幾天在devise和omniauth上觀看RailsCasts,然後通過相關教程來設置使用這些gem的認證系統。我認爲RailsCasts已經過時了,並且試圖用其他教程來彌補差距正在創造各種問題。Rails 4,Devise,Omniauth(與多個提供者)

請任何人都可以提出一個當前的教程,我可以用它作爲實現這個系統的基礎。我有單獨的用戶和身份驗證模型(用戶具有許多身份驗證)。

我真的很喜歡在rails 4上使用devise和omniauth(CanCan的能力),但在試圖找到一個基本設置(使用psql作爲數據庫)時,我的頭髮已經褪去。

在你初始化
+0

官方文檔是要走的路 – emaillenin

+0

我有這個相同的問題...任何解決方案? – 2014-02-20 21:08:36

+0

我發現這個:https://github.com/mohitjain/social-login-in-rails,但我不認爲它可以解決從Twitter連接用戶/身份驗證的問題。 Twitter不共享電子郵件,他的用戶模型使用電子郵件查找以前的記錄。嗯......希望有人能找到一個很好的解決方案。 – robertwbradford

回答

29

東西要使用設計不同,需要1多個模型的多個身份驗證提供者 - 授權

#authorization.rb 

# == Schema Information 
# 
# Table name: authorizations 
# 
# id   :integer   not null, primary key 
# user_id  :integer 
# provider  :string(255) 
# uid   :string(255) 
# token  :string(255) 
# secret  :string(255) 
# created_at :datetime 
# updated_at :datetime 
# profile_page :string(255) 
# 

class Authorization < ActiveRecord::Base 
    belongs_to :user 
end 

有代碼用戶模型

#user.rb 

SOCIALS = { 
    facebook: 'Facebook', 
    google_oauth2: 'Google', 
    linkedin: 'Linkedin' 
} 


has_many :authorizations 

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.name = auth.info.name 
    self.email = auth.info.email 
    self.photo = URI.parse(auth.info.image) 
end 

,並在結束時,你需要重寫爲設計控制器

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 first_login_path 
     else 
     redirect_to cabinet_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 

方法,如果你需要一些對供應商,例如Twitter你需要重寫twitter方法,因爲它不提供用戶郵件,你應該以其他方式保存它的credentails。

你也應該在路線

devise_for :users, 
      :controllers => { 
      :omniauth_callbacks => 'users/omniauth_callbacks', 
      } 
+6

感謝分享代碼!只是簡單的說明,授權與認證不同,omniauth關心的是用戶認證(你是誰),而像權威人士和cancan可以處理授權的寶石(我們知道你是誰,以下是你能做和不能做的)。只是爲了澄清新手進行編程的事情。 –

+2

非常感謝您的支持。實際上很難找到一個完整的,最新的工作解決方案。 – ahnbizcad

+0

在'users'下嵌套omniauth回調是做什麼的,爲什麼它是必要的? – ahnbizcad

2

嘗試做這樣的

#config/initializers/devise.rb 
    #provider1 
    config.omniauth :facebook, ENV['FACEBOOK_APP_ID'], ENV['FACEBOOK_SECRET'], 
    :site => 'https://graph.facebook.com/', 
    :authorize_path => '/oauth/authorize', 
    :access_token_path => '/oauth/access_token', 
    :scope => 'email, user_birthday, read_stream, read_friendlists, read_insights, read_mailbox, read_requests, xmpp_login, user_online_presence, friends_online_presence, ads_management, create_event, manage_friendlists, manage_notifications, publish_actions, publish_stream, rsvp_event, user_about_me, user_activities, user_birthday, user_checkins, user_education_history, user_events, user_groups, user_hometown, user_interests, user_likes, user_location, user_notes, user_photos, user_questions, user_relationships, user_relationship_details, user_religion_politics, user_status, user_subscriptions, user_videos, user_website, user_work_history' 

    #provider2 
    config.omniauth :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET'], 
    :scope => { 
    :secure_image_url => 'true', 
    :image_size => 'original', 
    :authorize_params => { 
     :force_login => 'true' 
    } 
    } 

    #provider3 
    config.omniauth :google_oauth2, ENV["GOOGLE_KEY"], ENV["GOOGLE_SECRET"] 
+1

這對我來說並不適用於強制Twitter使用戶重新登錄。它使用的是我以前在瀏覽器上的某個時間之前登錄過的帳戶。我試圖讓用戶可以將多個帳戶鏈接到他們的網站帳戶。 – Dex

+0

你可以創建一個auth控制器,屬於一個用戶和一個用戶has_many auths – MZaragoza

+0

我找到了答案。取出':scope =>',使用'omniauth-twitter' gem可以很好地工作。範圍是面向Facebook和其他一些服務的。 – Dex

3

一些變化,您應該給這個寶石一試。 https://github.com/AlexanderZaytsev/domp 快速且易於集成。我在30米左右有一個工作設置。

+0

那個寶石沒有爲我工作,可以請你分享你的例子。 – fenec

+0

這是我遇到的問題。 https://github.com/AlexanderZaytsev/domp/issues/16 – fenec

+0

我正在使用這顆寶石。雖然有一個小問題。當我轉到(本地主機:3000 /用戶/身份驗證/臉書)它給我沒有路線匹配錯誤。 但用耙指令我可以看到它定義在那裏 – zaingz

相關問題