djibouti33
djibouti33

Reputation: 12132

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.

Upvotes: 6

Views: 1604

Answers (1)

djibouti33
djibouti33

Reputation: 12132

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

Upvotes: 7

Related Questions