Как заставить Коалу хорошо играть с Омниавтом? - PullRequest
10 голосов
/ 10 августа 2011

Я пытаюсь заставить Коалу работать с Омниавтом. Пользовательская модель входит в систему через Facebook, используя Omniauth, и я хочу использовать 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  

Ответы [ 3 ]

12 голосов
/ 11 августа 2011

Проблема, о которой вы уже знаете, заключается в том, что fb_access_token доступен только в текущем сеансе и не доступен для Коалы.

Есть ли в вашей пользовательской модели столбец для хранения "токена"? Если нет, то убедитесь, что у вас есть этот столбец в пользовательской модели. Когда у вас есть этот столбец в пользовательской модели, вам нужно будет что-то сохранить в нем во время создания пользователя (метод create_with_omniauth в классе User). После успешной авторизации на Facebook вы должны обнаружить, что поле токена заполнено маркером oauth facebook. Если он заполнен, то ваш код Koala должен работать. В этом случае нет необходимости хранить учетные данные Facebook в сеансе.

Если, однако, вы не получаете автономный доступ от Facebook (что означает, что доступ предоставляется только на короткое время, то сохранение учетных данных facebook в сеансе имеет смысл. В этом случае вам не следует использовать «current_user.token», но сеанс ["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
0 голосов
/ 10 августа 2011

Ваша проблема заключается в том, что вы передаете неправильную вещь в Коалу:

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
0 голосов
/ 10 августа 2011

Избегайте записи, когда вы можете просто проверить это:

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

Я успешно использовал это приложение в качестве основы.

Я исправил несколько проблем, но пока не зафиксировал на github. Но они очень незначительны. Я думаю, что пример приложения работает.

Возможно, ваша проблема не в Коале, а в том, что токен не был сохранен, поэтому вы ничего не можете запросить или даже подключиться к Facebook.

...