4

I have a Rails web service running with Devise + OmniAuth. I have users authenticating against Facebook Connect on a mobile device. I then want the mobile device to establish a session with our web services. What do I need to pass to device from the mobile client to establish this session? Is there a code sample on the Rails side of things of how to handle this id+token that is passed from facebook -> mobile -> web service?

randombits
  • 47,058
  • 76
  • 251
  • 433

2 Answers2

4

I have not found a good way of doing this. I am not using :omniauthable either, I'm using OmniAuth and Devise separately as seen in the Railscast episode where there are two tables users and authentications. It's kinda hacky and only works for Facebook.

Basically, send your access_token from the iPhone to the server over SSL, or something similar. You have to check with OmniAuth first and if you are granted access, then you can manually create a session with OmniAuth by going something like:

I did get something to work by doing this though:

FB = OmniAuth::Strategies::Facebook.new("nothing") 

client = ::OAuth2::Client.new("nothing", "nothing", FB.client_options) 

cached_token = "app_id_part|session_id_part|token_part" # or maybe you sent it from the iPhone
access_token = ::OAuth2::AccessToken.new(client, cached_token)  

FB.instance_variable_set("@access_token", access_token) 

FB.auth_hash 
# You will either get a hash or get this error:
# OAuth2::AccessDenied: Received HTTP 401 during request.

After that you lookup the user info you need to find the user via your Authentications table:

@user = Authentication.where(:uid => FB.auth_hash["uid"], :provider => "facebook").first.user

Now we create a session:

sign_in_and_redirect(:user, @user)

# or, perhaps

sign_in(@user, :bypass => true)
Dex
  • 12,527
  • 15
  • 69
  • 90
  • Hey Dex, what omniauth-facebook gem are you using? I cannot get this to work using https://github.com/mkdynamic/omniauth-facebook – vinhboy Feb 01 '12 at 00:54
  • I used just plain ole Omniauth. It looks like Omniauth was recently overhauled, so this probably only works with version 0.3.2 and below. – Dex Feb 02 '12 at 23:58
2

I had a hard time with this, so I will post my answer here for anyone else. This is inspired by Dex's answer above.

FB = OmniAuth::Strategies::Facebook.new("APP_ID", "APP_SECRET") 
client = OAuth2::Client.new("APP_ID", "APP_SECRET", FB.options.client_options) 
token = OAuth2::AccessToken.new(client,'ACCESS_TOKEN', FB.options.access_token_options)
FB.access_token = token
FB.auth_hash

Any suggestions for improving this would be appreciated.

The snippet above allows me to get a auth_hash by querying facebook with the an access_token

I am using this gem: github.com/mkdynamic/omniauth-facebook

vinhboy
  • 8,542
  • 7
  • 34
  • 44
  • 1
    You don't really need the APP_ID and APP_SECRET, the whole point is to get the access token. The question is assuming you already got this from the mobile device. – Dex Feb 03 '12 at 00:13