2011-09-09 9 views
6

मैं स्क्रैच से प्रमाणीकरण को लागू करने के लिए Railscast Episode # 250 का उपयोग कर रहा हूं। हालांकि, अब मैं फेसबुक लॉगिन लागू करना चाहता हूं। मैंने पाया googling से कि OmniAuth और वसीयत रेलरेल पर omniauth के साथ फेसबुक लॉगिन को एकीकृत करना

हालांकि में यह करने के लिए प्रधानमंत्री के दावेदार हैं, इस उदाहरण पेज मुझे भ्रमित कर रहा है: https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview

इसमें कहा गया है:

रेल 3.0 के साथ

। 3, अपने Gemfile में इस का उपयोग रेल मुसीबत लोड हो रहा है OAuth कोर चल रहा है के बजाय यदि:

मणि "omniauth"

इसके बाद, आप में प्रदाता घोषित करने के लिए की जरूरत है अपने config/initializers/devise.rb:

config.omniauth: फेसबुक, "APP_ID", "APP_SECRET"

प्रश्न

omniauth हैं और वसीयत interelated?

मैं Railscast 250 के आधार पर मेरे प्रमाणीकरण में फेसबुक लॉगिन

उत्तर

8

लागू करने के लिए अपने विशिष्ट मामले में आप सोच सकते हैं कि वसीयत अपने आवेदन एक रूप (पूर्व का उपयोग कर उपयोगकर्ताओं को प्रमाणित करने की अनुमति देता है क्या करना चाहिए: एक ईमेल और पासवर्ड का उपयोग करके) या एक प्रमाणीकरण टोकन, Omniauth आपके एप्लिकेशन को उपयोगकर्ता प्रमाणित करने के लिए फेसबुक सर्वर पर "बोलने" की अनुमति देता है। दूसरे शब्दों में Omniauth Devise के शीर्ष पर बैठता है और आपके उपयोगकर्ता द्वारा प्रमाणीकृत तरीकों की संख्या को बढ़ाता है।

फेसबुक को लागू करने के लिए लॉग इन आप की जरूरत है:

0) कॉन्फ़िगर वसीयत: सिर्फ इस का पालन करें: https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview

1) आपके विचार में एक कड़ी है कि जब उपयोगकर्ता द्वारा क्लिक किया Omniauth बता शुरू करने के लिए "होगा पर्दाफाश "फेसबुक सर्वर से बात कर रहे हैं।

=link_to image_tag("facebook_64.png", :size => "64x64", :alt => "Facebook"), user_omniauth_authorize_path(:facebook, :display=>"dialog"), :title=>"Facebook" 

2) ताकि आप फेसबुक

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController 
    before_filter { @omniauth_hash = env["omniauth.auth"] } 

     # This method is responsible to create a registration_hash given an 
     # omniaauth_hash 
     # schama: https://github.com/intridea/omniauth/wiki/Auth-Hash-Schema 
     def self.build_registration_hash(omniauth_hash={}) 
     if (omniauth_hash["provider"].downcase.eql?("facebook")) 
      provider = "facebook" 
      # catch any excpetions thrown by code just to make sure we can continue even if parts of the omnia_has are missing 
      begin 
      first_name = omniauth_hash['user_info']['first_name'] 
      last_name = omniauth_hash['user_info']['last_name'] 
      sex  = omniauth_hash.fetch('extra', {}).fetch('user_hash',{})['gender'] 
      birthday = Date.strptime(omniauth_hash.fetch('extra', {}).fetch('user_hash', {})['birthday'],'%m/%d/%Y') if omniauth_hash.fetch('extra', {}).fetch('user_hash', {})['birthday'] 
      if omniauth_hash.fetch('extra', {}).fetch('user_hash', {})['timezone'] 
       utc_offset_in_hours = (omniauth_hash.fetch('extra', {}).fetch('user_hash', {})['timezone']).to_i 
       time_zone = (ActiveSupport::TimeZone[utc_offset_in_hours]).name 
      else 
       time_zone = nil 
      end 
      locale = omniauth_hash.fetch('extra', {}).fetch('user_hash', {})['locale'] 
      home_town = omniauth_hash.fetch('extra', {}).fetch('user_hash', {}).fetch('location', {})['name'] 
      if omniauth_hash.fetch('user_info', {})['image'] 
       photo_url = (omniauth_hash.fetch('user_info', {})['image']).gsub("=square","=large") #http://graph.facebook.com/531564247/picture?type=square 
      else 
       photo_url = nil 
      end 
      rescue => ex 
      logger.error("Error while parsing facebook auth hash: #{ex.class}: #{ex.message}") 
      sex  = nil 
      birthday = nil 
      time_zone = nil 
      locale = nil 
      home_town = nil 
      photo_url = nil 
      end 
     elsif omniauth_hash['uid'].downcase.include?("google.com") 
      provider = "google" 
      if omniauth_hash['user_info']['first_name'] and omniauth_hash['user_info']['last_name'] 
      first_name = omniauth_hash['user_info']['first_name'] 
      last_name = omniauth_hash['user_info']['last_name'] 
      elsif omniauth_hash['user_info']['name'] 
      first_name = omniauth_hash['user_info']['name'].split(' ')[0] 
      last_name = omniauth_hash['user_info']['name'].split(' ')[1] 
      else 
      first_name = nil 
      last_name = nil 
      end 
      sex  = nil 
      birthday = nil 
      time_zone = nil 
      locale = nil 
      home_town = nil 
      photo_url = nil 
     elsif omniauth_hash['uid'].downcase.include?("yahoo.com") 
      provider = "yahoo" 
      if omniauth_hash['user_info']['first_name'] and omniauth_hash['user_info']['last_name'] 
      first_name = omniauth_hash['user_info']['first_name'] 
      last_name = omniauth_hash['user_info']['last_name'] 
      elsif omniauth_hash['user_info']['name'] 
      first_name = omniauth_hash['user_info']['name'].split(' ')[0] 
      last_name = omniauth_hash['user_info']['name'].split(' ')[1] 
      else 
      first_name = nil 
      last_name = nil 
      end 
      sex  = nil 
      birthday = nil 
      time_zone = nil 
      locale = nil 
      home_town = nil 
      photo_url = nil 
     elsif omniauth_hash['uid'].downcase.include?("aol.com") 
      if omniauth_hash['user_info']['first_name'] and omniauth_hash['user_info']['last_name'] 
      first_name = omniauth_hash['user_info']['first_name'] 
      last_name = omniauth_hash['user_info']['last_name'] 
      elsif omniauth_hash['user_info']['name'] 
      first_name = omniauth_hash['user_info']['name'].split(' ')[0] 
      last_name = omniauth_hash['user_info']['name'].split(' ')[1] 
      else 
      first_name = nil 
      last_name = nil 
      end 
      provider = "aol" 
      sex  = nil 
      birthday = nil 
      time_zone = nil 
      locale = nil 
      home_town = nil 
      photo_url = nil  
     else 
      provider = "open_id" 
      if omniauth_hash['user_info']['first_name'] and omniauth_hash['user_info']['last_name'] 
      first_name = omniauth_hash['user_info']['first_name'] 
      last_name = omniauth_hash['user_info']['last_name'] 
      elsif omniauth_hash['user_info']['name'] 
      first_name = omniauth_hash['user_info']['name'].split(' ')[0] 
      last_name = omniauth_hash['user_info']['name'].split(' ')[1] 
      else 
      first_name = nil 
      last_name = nil 
      end 
      sex  = nil 
      birthday = nil 
      time_zone = nil 
      locale = nil 
      home_town = nil 
      photo_url = nil 
     end 

     h = { 
      :provider => provider, 
      :email  => omniauth_hash['user_info']['email'], 
      :profile_attributes => { 
      :first_name => first_name , 
      :last_name => last_name, 
      :avatar_url => photo_url, 
      :sex  => sex, 
      :birthday => birthday, 
      :time_zone => time_zone, 
      :locale  => locale, 
      :location => home_town 
      } 
     } 
     end 

     def process_callback 

     # The registration hash isolates the rest of the code from learning all the different structures 
     # of the omnia_hash 
     registration_hash = Users::OmniauthCallbacksController.build_registration_hash(@omniauth_hash) 
     logger.debug(registration_hash.to_yaml) 

     # Set the @user to nil 
     @user = nil 

     # Find if an authentication token for this provider and user id already exists 
     authentication = Authentication.find_by_provider_and_uid(@omniauth_hash['provider'], @omniauth_hash['uid']) 
     if authentication  # We found an authentication 
      if user_signed_in? && (authentication.user.id != current_user.id) 
      flash[:error] = I18n.t "controllers.omniauth_callbacks.process_callback.error.account_already_taken", 
      :provider => registration_hash[:provider].capitalize, 
      :account => registration_hash[:email] 
      redirect_to edit_user_account_path(current_user) 
      return 
      end 
     else 
      # We could not find the authentication than create one 
      authentication = Authentication.new(:provider => @omniauth_hash['provider'], :uid => @omniauth_hash['uid']) 
      if user_signed_in? 
      authentication.user = current_user 
      else 
      registration_hash[:skip_confirmation] = true 
      authentication.user = User.find_by_email(registration_hash[:email]) || User.create_user(registration_hash) 
      end 
     end 

     @user = authentication.user 
     # save the authentication 
     authentication.token = @omniauth_hash 
     authentication.provider_name = registration_hash[:provider] 
     authentication.provider_username = registration_hash[:email] 

     if !authentication.save 
      logger.error(authentication.errors) 
     end 

     # If a user is signed in then he is trying to link a new account 
     if user_signed_in? 
      if authentication.persisted? # This was a linking operation so send back the user to the account edit page 
      flash[:success] = I18n.t "controllers.omniauth_callbacks.process_callback.success.link_account", 
            :provider => registration_hash[:provider].capitalize, 
            :account => registration_hash[:email] 
      else 
      flash[:error] = I18n.t "controllers.omniauth_callbacks.process_callback.error.link_account", 
            :provider => registration_hash[:provider].capitalize, 
            :account => registration_hash[:email], 
            :errors =>authentication.errors 
      end 
      redirect_to edit_user_account_path(current_user) 
     else 
      # This was a sign in operation so sign in the user and redirect it to his home page 
      if @user.persisted? && authentication.persisted? 
      flash[:success] = I18n.t "controllers.omniauth_callbacks.process_callback.success.sign_in", 
      :provider => registration_hash[:provider].capitalize, 
      :account => registration_hash[:email] 
      sign_in_and_redirect(:user,@user) 
      else 
      session['registration_hash'] = registration_hash 
      flash[:error] = I18n.t "controllers.omniauth_callbacks.process_callback.error.sign_in", 
      :provider => registration_hash[:provider].capitalize, 
      :account => registration_hash[:email] 

      redirect_to new_registration_users_url 

      end 
     end 
     end 

     def facebook 
     process_callback 
     end 

     def gmail 
     process_callback 
     end 

अब के लिए प्रतिक्रिया करने आप देखेंगे कि मैं एक User.create_user (registration_hash फोन एक नियंत्रक को लागू करना फेसबुक सर्वर आप अनुप्रयोग कॉल करेंगे एक बिंदु पर)। इस विधि कार्यान्वयन अपने ऐप के एक उपयोगकर्ता बनाने पर निर्भर करेगा लेकिन कम से कम विधि एक उपयोगकर्ता बना सकते हैं और इसे करने के लिए एक यादृच्छिक पासवर्ड आवंटित करने के लिए है: मैं अन्य सेवा के साथ मेरा ऐप समर्थन लॉगिन इतना:

def self.create_user(registration_hash) 
    logger.info "Creating new user with registration hash: #{registration_hash.to_yaml}" 
    unless registration_hash or resigration_hash.empty? 
     return nil 
    end 
    user = User.new 
    user.email = registration_hash[:email] 
    if registration_hash[:password] 
     user.password = registration_hash[:password] 
    else 
     user.password = Devise.friendly_token[0,20] 
    end 
    user.password_confirmation = user.password 

    # custom app code here... 


    if registration_hash[:skip_confirmation] == true 
     user.confirm! 
    end 

    user  
    end 

नोट प्रमाणीकरण टोकन युक्त एक तालिका लागू की।

आशा है कि यह आपको शुरू कर सकता है।

+0

'संवाद' विकल्प को पदावनत किया जा रहा है। मुझे लगता है कि 'पॉपअप' इन दिनों बराबर है। – drewww

+0

अब, पॉपअप को भी हटा दिया गया है @ drewww –

संबंधित मुद्दे