I used devise and omniauth-facebook in my Rails 3 app for Facebook authentication, based on this tutorial: Adding Facebook auth to Rails 3.1 app, and it's working great!
But now I want to have full Facebook integration in my app, with which I can access the user's photos, friends, etc., and for that I am thinking of using fb_graph. fb_graph requires a token, and I wanted to know how to edit my user model to save the token and use it in fb_graph. Any help regarding this matter will be highly appreciated.
This is how my User model looks like right now:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
has_many :photos
has_many :scrapbooks
def self.find_for_facebook_oauth(access_token, signed_in_resource=nil)
data = access_token.extra.raw_info
if user = User.where(:email => data.email).first
user
else # Create a user with a stub password.
User.create!(:email => data.email, :password => Devise.friendly_token[0,20])
end
end
def self.new_with_session(params, session)
super.tap do |user|
if data = session["devise.facebook_data"] && session["devise.facebook_data"]["extra"]["raw_info"]
user.email = data["email"]
end
end
end
end
When your app uses Facebook Login to authenticate someone, it receives a User access token. If your app uses one of the Facebook SDKs, this token lasts for about 60 days. However, the SDKs automatically refresh the token whenever the person uses your app, so the tokens expire 60 days after last use.
You can do this:
User.create!(:email => data.email, :password => Devise.friendly_token[0,20], :authentication_token => access_token.credentials.token)
You will also need to add :authentication_token or whatever you named it to the attr_accessible
I was looking for the same thing. I tried to implement James Robey{s answer and felt into the same error: OAuthException :: An active access token must be used to query information about the current user
. Then I realized authentication_token was not being saved this way. After looking a while I found in FbGraph + OmniAuth + Facebook Graph API on Rails application a way to do it with session variables, by implementing the token saving during omniauth callback and then using it when calling fb_graph. So it might be something like this:
omniauth callback (app/controllers/users/omniauth_callbacks_controller.rb)
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
@user = User.find_for_facebook_oauth(request.env["omniauth.auth"], current_user)
if @user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Facebook"
# this part is where token is stored
auth = request.env['omniauth.auth']
token = auth['credentials']['token']
session[:fb_access_token] = token
#
sign_in_and_redirect @user, :event => :authentication
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
end
Then when calling fb_graph
@fb_user = FbGraph::User.new('me', access_token: session[:fb_access_token]).fetch
I don't know if it's the best way, but works so far.
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