The Run Around

From Facebook Developer Wiki

Jump to: navigation, search

These are some notes I made by exploring the source of The Run Around. If there are errors or omissions, please fix.

Links:


Contents

[edit] Database Structure

  • users table: username (varchar(255), primary key), name, password, email, fb_uid, email_hash (varchar(64))
  • runs table: id, username, date, miles, route

[edit] Authentication Process

See How Connect Authentication Works for how this works from the Facebook side. Here's how it works from the app's point of view:

[edit] Initial Page (index.php)

  • determines if user is logged in by calling User::getLoggedIn(). If successful, $user is set.
  • dispatches to "Front Page when logged out" (below) if $user not set
  • otherwise, displays page with correct user info.

[edit] Determining if a user is logged in, User::getLoggedIn (lib/user.php)

  • checks cookies (via getLoggedInNative) for indication that the user is logged into the site-specific auth mechanism ("native" auth). This returns a User object; store this in $native_user.
  • asks facebook api to check cookies for indication that this user is logged into facebook, via facebook_client()->get_loggedin_user(). This returns a Facebook uid; store this in $fb_uid.
    • Note that the Javascript facebook client scripts have to run and present a login/"agree to TOS" dialog to set up these cookies for the first time.
    • This is not an asynchronous call to the Facebook Web service - the uid can be retrieved using only cookies.
  • If $fb_uid is set, determines whether a user (in the users table) exists for the given Facebook UID.
  • Takes action based on the following truth table:
$native_user set $fb_uid set Found a User for $fb_uid Action
000 Return false (not logged in)
011 Return the User found from $fb_uid
100 Return $native_user
010 Create a new User from $fb_uid and return it (see below)
110 Connect $native_user (User::connectWithFacebookUID) by updating its $fb_uid in the db, and return $native_user
111 Connect $native_user (User::connectWithFacebookUID) by updating its $fb_uid in the db, delete the old user associated with $fb_uid, and return $native_user.

[edit] How to create a User based on $fb_uid (User::createFromFacebookUID in lib/user.php)

  • searches for a user in the users table with a matching email address
    • note: it actually checks the email hashes, not the address itself
  • if found, just updates that user's fb_uid field and returns it.
  • otherwise, makes up a new user object with name "FacebookUser_uid", no password and matching fb_uid.

[edit] Front Page when logged out (render_logged_out_index() in lib/display.php)

  • displays a login form, which submits to login.php
  • displays an FBConnect button, which is just an XFBML tag (defined in lib/fbconnect.php, render_fbconnect_button) with onClick bound to facebook_button_onclick()

[edit] facebook_button_onclick() (fbconnect.js)

  • The button is created via XFBML's fb:login-button tag. So when it is clicked, it has code that runs within the JS client library internals. It calls FB.Connect.requireSession() (see below).
  • ensures the facebook javascript stuff is initialised (ensure_init in fbconnect.js), which may asynchronously download scripts from Facebook's site, so pass a callback to ensure_init. More about it may be found (if you are lucky) at Using the Facebook JavaScript Client Library. This can be mostly ignored; most of the time the callback will be called immediately.
  • calls get_sessionState().waitUntilReady() to set it up such that when Facebook considers the user logged in (has a session state), it will continue the function. See below.

[edit] callback function (fbconnect.js)

  • Called when the Facebook backend has a session id ready (with a logged in user). The authentication process is done. If it worked (FB.Facebook.apiClient.get_session().uid has a value) then the page is refreshed and the whole process restarts, except that hopefully the login check will successfully find or create a user.

[edit] Detour: how requireSession() works (facebook js client library internals)

  • examines the cookies to figure out which of these three states the session is in: not logged in; app not authorized (but logged in); connected (and authorized and logged in).
    • if not logged in, displays a login dialog (via iframe (preferred), popup, or redirect) asking the user to login.
    • if not authorized, displays a similar dialog, but only with the TOS links for facebook and the site.
    • if connected, does nothing.
  • Once the user finishes with the dialog, the iframe disappears, the Facebook session cookies are set for the site, and anyone who is waiting on the session (via get_sessionState().waitUntilReady()) is notified. This includes the above callback function.


[edit] Inviting Friends Process

[edit] Post Authorize Ping (fb_notification_receiver.php) =

  • This URL is hit when Facebook notices that a user has authorized your app. (e.g., because they say "yes!" to friend invite)
  • checks cookies to figure out the relevant facebook user
  • examines the data given, including a list of usernames associated with that user that we provided in a previous step (find out?)
  • for each username given, see if it exists in our database. If so, connect it with the facebook uid given by updating its $fb_uid in the db, and deleting any other existing users with that fb_uid.
reference