Authlogic Facebook Connect Snafu
Hey, maybe I can help on this one, just had this problem not very long time ago...
Facebook connect is outdated. All the cool kids are now using Facebook Graph with OAuth. Facebook team have even closed the documentation for Facebook Connect.
Anyway, that goes for Authlogic Facebook connect, it simply does not work anymore.
In the end, I kept using Authlogic for normal login and account management, but for Facebook connect I wrote my own code.
Chances are you may have used facebooker gem. Uninstall that gem, but keep the config/facebooker.yml file.
Try this:
Keep using config/facebooker.yml by adding this code inside config/initializers/load_config.rb (you need to create this file)
config = YAML.load_file("#{Rails.root}/config/facebooker.yml") || {}
facebook_config = config['common'] || {}
facebook_config.update(config[Rails.env] || {})
FB_CONFIG = facebook_config.symbolize_keys
Add this code inside your user_controller.rb:
def facebook_oauth_callback
if not params[:code].nil?
callback = url_for(:host => APP_CONFIG[:host], :controller => 'gallery/user', :action => 'facebook_oauth_callback')
url = URI.parse("https://graph.facebook.com/oauth/access_token?client_id=#{FB_CONFIG[:application_id]}&redirect_uri=#{callback}&client_secret=#{FB_CONFIG[:secret_key]}&code=#{CGI::escape(params[:code])}")
http = Net::HTTP.new(url.host, url.port) http.use_ssl = (url.scheme == 'https') tmp_url = url.path + "?" + url.query
request = Net::HTTP::Get.new(tmp_url)
response = http.request(request)
data = response.body
access_token = data.split("=")[1]
if access_token.blank?
flash[:notice] = 'An error occurred while connecting through Facebook, please try again later.'
else
url = URI.parse("https://graph.facebook.com/me?access_token=#{CGI::escape(access_token)}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = (url.scheme == 'https')
tmp_url = url.path + "?" + url.query
request = Net::HTTP::Get.new(tmp_url)
response = http.request(request)
user_data = response.body
user_data_obj = JSON.parse(user_data)
@user = User.new_or_find_by_facebook_oauth_access_token(access_token, {:user_data => user_data_obj})
if @user.new_record?
session[:user] = @user
session[:external_app] = "Facebook"
redirect_to(:action => 'new_details')
else
user_session = UserSession.create(@user)
flash[:notice] = "Successfully logged in."
redirect_back_or_default root_url
end
end
end
end
def create_facebook
redirect_to("https://graph.facebook.com/oauth/authorize?client_id=#{FB_CONFIG[:application_id]}&redirect_uri=" +
url_for(:host => APP_CONFIG[:host], :controller => 'gallery/user', :action => 'facebook_oauth_callback') +
"&scope=email,offline_access")
end
- Add the find method inside your User model (app/models/user.rb):
def self.new_or_find_by_facebook_oauth_access_token(access_token, options = {})
user = User.find_by_facebook_oauth_access_token(access_token)
if user.blank?
#code to create new user here
end
user
end
Add link to action create_facebook in the view, something like
<%= link_to image_tag('gallery/button-facebook.png', :title => "register with Facebook", :alt => "register with Facebook"), {:action => 'create_facebook'}, {:target => '_parent'} %>
- In the first step you created a file to get config data from facebooker.yml
- In second step, you basically created two functions, one for sending user to facebook site (create_facebook) and another to capture the callback data (facebook_oauth_callback) the idea was from this page: http://www.wisejive.com/2010/05/facebook-oauth-on-rails.html
- In third step, you just added a method inside User model to find, or create new if not found, a user based on the information returned from facebook.
Session bug using facebook-connect-with-authlogic in Rails
Yes you should be able to still use the cookies and sessions in harmony; Facebook sets & uses cookies (afaik) regardless of how your application's sessions are configured.
The cattr_accessor :current_user
is used elsewhere in our application (for reasons I can't recall right now) and should really be left out of the post. Thanks for bringing it up! Yes, there should still be a current_user
method in ApplicationController
.
Apologies that it took so long to respond, you sent the Twitter message to me at 1am my time, I read it at 3am (due to somebody drumming next door) and I've been busy today up until now (4pm)! I sincerly hopes this helps and if you need more help I should be around for a while yet!
Ruby on Rails: Authlogic Facebook integration: Link accounts with user input instead of automatically using email address
Someone else may be able to point you at the perfect gem for this, but I can tell you that I've worked on a similar problem and it wasn't much work to roll our own, based on the oauth2 gem.
Here's a sketch of the code/flow I use.
1) User clicks on 'Connect to Facebook' and this sends you to an action like this
def to_facebook
options = {
:redirect_uri => facebook_callback_url,
:scope => "email,publish_stream" # whatever you want to do
}
client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_API_SECRET, :site => FACEBOOK_API_SITE)
redirect_to client.web_server.authorize_url(options)
end
2) User goes over to facebook and gives you all the access you want, then facebook calls the callback you specified facebook_callback_url
which should take you to an action like this:def facebook_callback
client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_API_SECRET, :site => FACEBOOK_API_SITE)
access_token = client.web_server.get_access_token(params[:code], :redirect_uri => facebook_callback_url)
do_my_custom_user_association(access_token)
end
Then you can specify whatever you want in do_my_custom_user_association
, you should have a current_user
available from authlogic if someone is logged in, so you can redirect to a flow that lets the logged in user select if they want to merge into their current account or a different one. If there's no current user, you can send them to a create account flow, with some facebook data attached.Note that this is just a sketch, there are error cases to handle (e.g. facebook_callback will be hit with the param error_reason
if the get_acccess_token
fails) and I'm not recommending you do all the oauth2 interaction right in your controller, but the basic idea is there.
See http://developers.facebook.com/docs/authentication/ if any of the oauth2 interactions don't make sense.
Login with Facebook with authlogic and omniauth-facebook
Please take a look to my response on:
Devise, Omniauth and Facebook integration session error
You can find more tutorial on:
https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview
single-sign-on authentication using Facebook on Rails -- AuthLogic or Devise?
Here are a railscast about devise + omniauth:
simple omniauth
You'll also find on the same website two others railscasts about devise and omniauth.
Authlogic Facebook Connect and cucumber
I had the same issue with my test suite after installing authlogic_facebook_connect.
I applied the following patch to the plugin and it solved the problem:
http://gist.github.com/221893
Related Topics
Why Should @@Class_Variables Be Avoided in Ruby
Ruby: How to Escape Url with Square Brackets [ and ]
How to Test Strong Params with Rspec
Rails3 Scope for Count of Children in Has_Many Relationship
In Ruby, How to Be Warned of Duplicate Keys in Hashes When Loading a Yaml Document
Ruby - Generate All Two Letter Words
International Chars Using Rspec with Ruby on Rails
If I Have a Stripe Token from a Charge, How to Get Its Charge Id
Broken Rails Routes After Implementing Single Table Inheritance
How to Avoid Circular Creation of Associated Models in Factory_Girl
How to Check If an Object Is Nil in a View in Ruby
Puzzled Over Palindromic Product Problem
How to Set in a Middleware a Variable Accessible in All My Application