Assuming we have registered an app with Facebook we need two things to get basic integration with Facebook Connect. A link so the user can trigger the auth request and an end-point for Facebook to send the user and their authorization/authentication credentials to.
Add a link to https://graph.facebook.com/oauth/authorize passing as params our app_id, what permissions we want and what callback URL we want FB to hit on successful auth. The link would look a little like:
<a href="https://graph.facebook.com/oauth/authorize?client_id=1234567890&redirect_uri=https://modcloth.com/auth/facebook/callback&scope=publish_stream,offline_access,email,user_location,user_birthday">
<img src="/images/fb_connect.png" alt="Sign in with Facebook" />
</a>
Or we could use mini_fb which gives us some helpers for working with FB's API
- oauth_url ||= MiniFB.oauth_url('1234567890', 'https://modcloth.com/auth/facebook/callback', :scope => "publish_stream,offline_access,email,user_location,user_birthday")
= link_to image_tag('fb_connect.png', :alt => 'Sign in with Facebook'), oauth_url
http://developers.facebook.com/docs/authentication/
For this prototype, all we need to do is set a session for a new or existing user. The callback from Facebook gives us a short-lived access_token
. We then use this access_token
and some other params to query Facebook for the user's data. We'll do it in one action here for illustrative purposes.
def facebook_callback
code = params['code'] # Facebook's verification string
if code
# setting up OAuth credentials
# fb_secret is part of the credentials we get when we
# register an app, along with the app_id ('123456789')
access_token = MiniFB.oauth_access_token('1234567890', 'https://modcloth.com/auth/facebook/callback', fb_secret, code)['access_token']
# make a reqest to FB API to get the 'me' resource, authenticated with the access_token
res = MiniFB.get(access_token, 'me')
# we hopefully don't need this anymore but I've experienced FB returning different wrapping around
# their response depending on how much they're messing with me that week.
response = res.keys.include?('response') ? res.response : res
# the response hash includes our data from fb like their (Facebook's) UID for our user, email, first_name, last_name etc.
# http://developers.facebook.com/docs/reference/api/user/
account = User.find_or_create_by_email(response['email'])
# set session cookie in the normal manner now that we have "authenticated" an account
self.current_user = account
end
redirect_to '/somewhere_else'
end
http://developers.facebook.com/docs/reference/api/user/
And that's kinda it.
Later on we might choose to save the user's access_token so we can make further API calls. I usually stick this in an authentications table along with the network's uid and some string or value to let me know what social network this is for.
create_table "authentications", do |t|
t.integer "account_id"
t.string "provider"
t.string "uid"
t.string "access_token"
t.datetime "created_at"
t.datetime "updated_at"
end