【问题标题】:How to get Koala to play nicely with Omniauth?如何让考拉与 Omniauth 配合得很好?
【发布时间】:2011-10-24 02:45:38
【问题描述】:

我正试图让考拉与 Omniauth 合作。一个用户模型使用 Omniauth 登录 Facebook,我想使用 Koala 作为客户端来提取正在使用该应用程序的用户朋友列表。我似乎没有正确保存令牌:

控制器

@friends = Array.new
 if current_user.token
   graph = Koala::Facebook::GraphAPI.new(current_user.token)
   @profile_image = graph.get_picture("me")
   @fbprofile = graph.get_object("me")
   @friends = graph.get_connections("me", "friends")
end

数据库架构

create_table "users", :force => true do |t|
  t.string   "provider"
  t.string   "uid"
  t.string   "name"
  t.datetime "created_at"
  t.datetime "updated_at"
  t.string   "token"
end

用户模型有

def self.create_with_omniauth(auth)  
  create! do |user|  
    user.provider = auth["provider"]  
    user.uid = auth["uid"]  
    user.name = auth["user_info"]["name"]  
  end  
end

Koala.rb 初始化器有:

module Facebook
  CONFIG = YAML.load_file(Rails.root.join("config/facebook.yml"))[Rails.env]
  APP_ID = CONFIG['app_id']
  SECRET = CONFIG['secret_key']
end

Koala::Facebook::OAuth.class_eval do
  def initialize_with_default_settings(*args)
    case args.size
      when 0, 1
        raise "application id and/or secret are not specified in the config" unless Facebook::APP_ID && Facebook::SECRET
        initialize_without_default_settings(Facebook::APP_ID.to_s, Facebook::SECRET.to_s, args.first)
      when 2, 3
        initialize_without_default_settings(*args) 
    end
  end 

  alias_method_chain :initialize, :default_settings 
end

会话控制器有:

  def create  
    auth = request.env["omniauth.auth"]  
    user = User.find_by_provider_and_uid(auth["provider"], auth["uid"]) || User.create_with_omniauth(auth)
    session[:user_id] = user.id  

    session['fb_auth'] = request.env['omniauth.auth']
    session['fb_access_token'] = omniauth['credentials']['token']
    session['fb_error'] = nil

    redirect_to root_url 
  end  

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 facebook-graph-api omniauth koala


    【解决方案1】:

    当你可以测试时避免写作:

    https://github.com/holden/devise-omniauth-example/blob/master/config/initializers/devise.rb

    我以该应用为基础取得了成功。

    我已经修复了一些问题,但尚未在 github 上提交。但这些都是非常小的。我认为示例应用程序有效。

    您的问题可能不是考拉,而是令牌未保存,因此您无法查询任何内容,甚至无法连接到 Facebook。

    【讨论】:

      【解决方案2】:

      您的问题似乎是您将错误的东西传递给考拉:

      if @token = current_user.token
         @graph = Koala::Facebook::GraphAPI.new(oauth_callback_url)
         @friends = @graph.get_connections("me", "friends")
      end
      

      尝试将其更改为以下内容:

      @friends = Array.new # I think it returns a straight array, might be wrong.
      if current_user.token
         graph = Koala::Facebook::GraphAPI.new(current_user.token)
         @friends = graph.get_connections("me", "friends")
      end
      

      【讨论】:

      • 这是因为您没有将令牌存储在 create_with_omniauth 方法中。
      【解决方案3】:

      您已经知道的问题是 fb_access_token 仅在当前会话中可用,而对 Koala 不可用。

      您的用户模型是否有一个列来存储“令牌”?如果没有,请确保您在用户模型中有该列。当您在用户模型中有该列时,您需要在创建用户时在其中存储一些内容(User 类中的 create_with_omniauth 方法)。从 facebook 成功授权后,您应该会发现 token 字段填充了 facebook oauth 令牌。如果已填充,那么您的考拉代码应该可以工作。在这种情况下,无需在会话中存储 facebook 凭据。

      但是,如果您没有从 Facebook 获得离线访问(这意味着访问仅在短时间内提供,那么将 facebook 凭据存储在会话中是有意义的。在这种情况下,您不应使用“current_user.token”,而是session["fb_auth_token"] 用考拉代替。

      希望这会有所帮助!

      因此,如果您想离线访问(长期存储 facebook 授权),请将您的模型代码更改为存储 fb_auth_token,如下所示

      # User model
      def self.create_with_omniauth(auth)  
        create! do |user|  
          user.provider = auth["provider"]  
          user.uid = auth["uid"]  
          user.name = auth["user_info"]["name"]  
          user.token = auth['credentials']['token']
        end  
      end
      
      # SessionsController
      def create  
        auth = request.env["omniauth.auth"]  
        user = User.find_by_provider_and_uid(auth["provider"], auth["uid"]) || User.create_with_omniauth(auth)
        # Note i've also passed the omniauth object      
      
        session[:user_id] = user.id  
        session['fb_auth'] = auth
        session['fb_access_token'] = auth['credentials']['token']
        session['fb_error'] = nil
      
        redirect_to root_url 
      end 
      

      如果您有短期访问权限,则将“其他”控制器更改为使用会话

      # The other controller
      def whateverthissactionis
        @friends = Array.new
        if session["fb_access_token"].present?
          graph = Koala::Facebook::GraphAPI.new(session["fb_access_token"]) # Note that i'm using session here
          @profile_image = graph.get_picture("me")
          @fbprofile = graph.get_object("me")
          @friends = graph.get_connections("me", "friends")
        end
      end
      

      【讨论】:

        猜你喜欢
        • 2014-04-07
        • 2019-05-18
        • 2010-09-11
        • 1970-01-01
        • 2016-08-18
        • 1970-01-01
        • 1970-01-01
        • 2011-11-27
        • 1970-01-01
        相关资源
        最近更新 更多