Ruby   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了ruby-on-rails-3 – 将facebook登录与omniauth集成在rails上大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用 Railscast Episode # 250从头开始实现身份验证.但是,现在我想实现Facebook登录.从谷歌搜索我发现OmniAuth和Devise是在Rails中做到这一点的主要竞争者

但是,这个示例页面让我很困惑:https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview

它指出:

omn​​iauth和devise是否相互关联?

在基于Railscast 250的身份验证中,我该怎么做才能实现Facebook登录

解决方法

在您的特定情况下,您可以认为Devise允许您的应用程序使用表单(例如:使用电子邮件和密码)或身份验证令牌对用户进行身份验证,Omniauth允许您的应用程序与Facebook服务器“对话”以对用户进行身份验证.换句话说,Omniauth位于Devise之上,并扩展了用户可以进行身份​​验证的方式.

要实现Facebook登录,您需要:

0)配置设计:只需遵循:https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview

1)在您的视图中显示一个链接,当用户点击时会告诉Omniauth开始“说话”到Facebook服务器.

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

2)Facebook服务器有一次会调用你的应用程序,所以你必须实现一个控制器来响应Facebook

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-scheR_441_11845@a
      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',{})['@R_944_11064@er']
            birthday   = Date.strptime(omniauth_hash.fetch('extra',{})['birthday'],'%m/%d/%Y') if omniauth_hash.fetch('extra',{})['birthday']
            if omniauth_hash.fetch('extra',{})['timezone']
              utc_offset_in_hours = (omniauth_hash.fetch('extra',{})['timezone']).to_i 
              time_zone = (ActiveSupport::TimeZone[utc_offset_in_hours]).name
            else
              time_zone = nil
            end
            locale    = omniauth_hash.fetch('extra',{})['locale'] 
            home_town = omniauth_hash.fetch('extra',{}).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",:account => registration_hash[:email]
          else
            flash[:error] = I18n.t "controllers.omniauth_callBACks.process_callBACk.error.link_account",: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",: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",: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).此方法实现将取决于您的应用程序如何创建用户,但至少该方法必须@R_833_10589@并为其分配随机密码:

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

注意:我的应用程序支持使用其他服务登录,因此我实现了一个包含身份验证令牌的表.

希望这可以帮助你入门.

大佬总结

以上是大佬教程为你收集整理的ruby-on-rails-3 – 将facebook登录与omniauth集成在rails上全部内容,希望文章能够帮你解决ruby-on-rails-3 – 将facebook登录与omniauth集成在rails上所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。