Auth

Facebook Connect provides the great benefit of removing the registration process by allowing the User to login to your site with their Facebook account. This is achieved by sharing the logged-in user state between http://www.facebook.com/ and your site http://www.example.com/. A Connected user remains logged-in to your site as long as they are logged-in to Facebook.

This means you get to skip a lot of the boring stuff when you're building your hot new application. No need for a registration flow, or uploading a new Profile Picture, or remembering your username. But not only that, you also get the user's social graph, and many other useful pieces of information. Facebook Connect can also be used with your existing User management system as many sites already do.

Status & Sessions

FB.loginStatus(), FB.login() and FB.logout() return a response object containing these properties:

Property Description
status Status of unknown, notConnected or connected.
session Session Object.
perms Comma separated list of permission names (perms).

Example:

FB.login(function(response) {
  alert(
    'Status: ' + response.status +
    '\nUID: ' + (response.session ? response.session.uid : 'unavailable') +
    '\nPerms: ' + response.perms
  );
}, 'email');

Status

The status allows you to distinguish between 3 possible states:

Status Description
unknown Facebook doesn't know who the user is.
notConnected Known user who hasn't authorized your application.
connected Known user who has authorized your application.

Session

Sessions are how you identify users, gain access to their data and perform interactive actions. Facebook is the authority for Sessions, and shares login state with your Connect enabled site. Sessions are attached to your API key, and will only be issued to your application's domain. The session is comprised of:

Property Description
uid The User ID.
session_key Session Key for making API calls.
secret Session Secret for making API calls.
expires Unix Timestamp of Session expiry time.
signature Signature for the Session based on your API Secret.

Perms

Currently this is a comma separated list of perms names granted for a specific call. This will be changing soon.

Flows

Its convenient to think of various independent flows with respect to authentication. This makes it easy to understand common flows and approaches and how to handle them.

  • The code shown below is for conceptual understanding rather than literal examples. There are real examples too.
  • The DOM access and event handlers in the JavaScript are using the lowest common denomination in browsers to focus on the Mu aspects of the code. For a real world site, you probably want to use one of the various JavaScript libraries instead.
  • The code uses a unit test style approach to indicate what behaviours are expected in a given flow.

Logged Out User

  1. User is not logged into www.facebook.com
  2. User visits www.example.com
  3. www.example.com does not get a session

This is the unknown status. If www.facebook.com does not know who the user is, it cannot tell www.example.com anything about them. The user may be Connected with your site, just not logged in. Or they may be someone new to www.example.com as well as www.facebook.com. Example:

FB.loginStatus(function(response) {
  assert(!response.session, 'a session object will not be available');
  assert(response.status == 'unknown', 'status is unknown');
});

notConnected User

  1. User is logged into www.facebook.com
  2. User has not authorized www.example.com
  3. User visits www.example.com
  4. www.example.com does not get a session

This is the notConnected status. In this case www.facebook.com knows who the user is, but it cannot tell www.example.com anything about them because the User has not authorized this action. Example:

FB.loginStatus(function(response) {
  assert(!response.session, 'a session object will not be available');
  assert(response.status == 'notConnected', 'status is notConnected');
});

Connected User

  1. User is logged into www.facebook.com
  2. User has authorized www.example.com
  3. User visits www.example.com
  4. www.example.com gets a session

This is the connected status. In this case www.facebook.com knows who the user is, and the user has authorized www.example.com. So it will return a session to www.example.com. Example:

FB.loginStatus(function(response) {
  assert(response.session, 'a session object will be available');
  assert(response.status == 'connected', 'status is connected');
});

Connect with Facebook

  1. User visits www.example.com
  2. www.example.com does not get a session
  3. www.example.com shows User a Connect with Facebook button

Typically, you will not differentiate between the Logged Out User status and the notConnected User status. You should ignore the status property of the response, and use the session property to decide what to do. Example:

FB.loginStatus(function(response) {
  if (response.session) {
    showUserInfo();
  } else {
    showConnectWithFacebookButton();
  }
});

If a session is not available, you should show the user a Connect with Facebook button. For example, using the large button which triggers the login flow when clicked:

<img
  id="facebook-login"
  style="cursor: hover;"
  src="http://static.ak.fbcdn.net/images/fbconnect/login-buttons/connect_white_large_long.gif">
<script>
  document.getElementById('facebook-login').onclick = function() {
    FB.login(function(response) {
      if (response.session) {
        alert('Thank you for logging in.');
      } else {
        alert('You need to login to use www.example.com');
      }
    });
  };
</script>

Login to www.facebook.com and www.example.com

  1. User has a Facebook account
  2. User is not logged into www.facebook.com
  3. User visits www.example.com
  4. www.example.com does not get a session
  5. www.example.com shows User a Connect with Facebook button
  6. User logs into www.facebook.com and www.example.com

Once you showed the user the Connect with Facebook button, and they clicked on it, they will be promped to login. Here's what the login popup looks like:

images/login.png

Here the user can login into Facebook, and grant your application a session in one step. This works for both a User that has never used www.example.com or a returning user.

Authorize www.example.com

  1. User has a Facebook account
  2. User is logged into www.facebook.com
  3. User visits www.example.com
  4. www.example.com does not get a session
  5. www.example.com shows User a Connect with Facebook button
  6. User Authorizes www.example.com

If the User is already logged in to Facebook, but has not authorized www.example.com, then clicking on the Connect with Facebook button will trigger a dialog confirming the user wants to authorize www.example.com. Here's what the Authorization dialog looks like:

images/tos.png

New User Sign-Up

  1. User does not have a Facebook account
  2. User visits www.example.com
  3. www.example.com does not get a session
  4. www.example.com shows User a Connect with Facebook button
  5. User sign's up for a new account and authorizes www.example.com

If the user does not have a Facebook account, they can click on the Sign up for Facebook link on the bottom left of the login screen (from the Login to www.facebook.com and www.example.com flow) to sign up and authorize your site in one step. Here's what the sign-up process looks like:

images/signup.png

Coding Approaches

Depending on how your application is built, there are a few different techniques that can be applied to help manage the user state.

I want to store the session on the server, no Cookies please

Advanced Technique.

If you are very performance concious, then you may not want the Cookie overhead if you are already using server sessions identified via your own Cookie. In this case, you may have a server end point which can accept a Facebook session and store it against your server session. Don't forget the Signature Validation process on the server.

On each page load, you must return the session (or null) to the front end. This is required as Mu needs the active user session to allow using its functionality. Here's an example, which initializes Mu with the session returned by your server, and sets up a status handler to call a hypothetical updateSessionOnServer function to notify the server of the change in session:

// session from the server
var serverSession = { ... };

// initialize the library
FB.init({
  apiKey: 'YOUR API KEY',
  cookie: false,         // disable cookie support
  session: serverSession // provide the default session (can be null)
});

// if the session changes, we update it on the server (not shown here).
FB.Event.subscribe('auth.sessionChange', function(response) {
  updateSessionOnServer(response.session);
  serverSession = response.session;
  // do something else, or maybe refresh the page
});