6

Our Rails 3 app uses facebook-omniauth, allowing users to authenticate with facebook.

It'd be nice to use as much of the web based authentication system as possible, so I tried following the answer (the one that hasn't been down-voted) to this SO question but I can't get it to work.

The gist of the answer is:

omniauth-facebook will handle requests to the callback endpoint with an access_token parameter without any trouble. Easy :)

So to test this, in my browser I'm issuing the following request:

/users/auth/facebook_api/callback?access_token=BAAB...

But in my server log, I see:

(facebook) Callback phase initiated.
(facebook) Authentication failure! invalid_credentials: OAuth2::Error, : 
{"error":{"message":"Missing authorization code","type":"OAuthException","code":1}}

I can't figure out what I'm doing wrong. Is the fact that I'm trying to do this through the browser to test messing something up? Any other ideas on how I can reuse my www based auth logic for my ios app?

UPDATE: I'm not sure, but I'm following this guide in order to have multiple facebook omniauth strategies, one for www and another for mobile.

2
  • Did you find an answer for this? I'm having exactly the same problem! This is my question stackoverflow.com/questions/14341867/… Commented Jan 15, 2013 at 20:58
  • 1
    Unfortunately I didn't, but I just posted my workaround as an official answer. I don't know how the poster in the question I linked to got his solution to work, but I absolutely couldn't. Commented Jan 16, 2013 at 0:02

1 Answer 1

7

I never found a solution in line with what I was asking originally, but here is how I solved it: Take the access token you get on the iPhone and send it up to your server and perform the login manually.

def facebook_login
  graph = Koala::Facebook::API.new(params[:user][:fb_access_token])
  profile = graph.get_object('me')
  omniauth = build_omniauth_hash(profile)

  @user = User.find_or_create_for_facebook_oauth(omniauth)
end

On www we already had a method called find_or_create_for_facebook_oauth, and that took the result from Omniauth and either found the user or created a new one. In order to utilize that method for mobile, I had to build up a similar structure by hand so I could pass it as an argument.

def build_omniauth_hash(profile)
  struct = OpenStruct.new
  struct.uid = profile['id']
  struct.info = OpenStruct.new
  struct.info.email = profile['email']
  struct.info.image = "http://graph.facebook.com/#{profile['id']}/picture?type=square"
  struct.info.first_name = profile['first_name']
  struct.info.last_name = profile['last_name']
  struct.info.bio = profile['bio']
  struct.info.hometown = profile['hometown']['name'] if profile['hometown']
  struct.info.location = profile['location']['name'] if profile['location']
  struct
end
Sign up to request clarification or add additional context in comments.

1 Comment

thanks man, I'll do this and if I found something else I'll update you here!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.