I'm trying to get Koala to work with Omniauth. A User model logs in with Facebook using Omniauth and I want to use Koala as a client to pull the list of a user's friends that are using the app. I don't seem to be saving the tokens properly:
Controller
@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
DB Schema
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
User model has
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 initializer has:
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
Sessions controller has:
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
The problem like you already know is that the fb_access_token is only available in the current session and not being available to Koala.
Does your user model have a column to store "token"? If not, then make sure you have that column in the user model. When you have that column in the user model, you will need to store something in it at the time you create the user (create_with_omniauth method in the User class). After successfull authorization from facebook you should find that the token field is populated with the facebook oauth token. If it is populated, then your Koala code should work. In this case there is no need to store the facebook credentials in the session.
If however you are not getting offline access from Facebook (which means the access is only provided for a short duration, then storing the facebook credentials in the session makes sense. In this case you should not use "current_user.token" but session["fb_auth_token"] instead with Koala.
Hope this helps!
So if you want offline access (long term storage of facebook authorization), change your model code to store fb_auth_token as below
# 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
If you have short term access then change your "other" controller to use sessions
# 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With