Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authenticate user from iOS Rails 3 server and Omniauth

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.

like image 724
djibouti33 Avatar asked Oct 10 '12 19:10

djibouti33


1 Answers

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
like image 173
djibouti33 Avatar answered Oct 20 '22 14:10

djibouti33