Authentication Model for JavaScript API

From Facebook Developer Wiki

Jump to: navigation, search

In order for an application to make Facebook Platform API calls using JavaScript code from a browser, it needs to authenticate with Facebook. This document describes the authentication model we use for this usage.

[edit] Objective of Authentication

For this type of application, we settled on the following design objectives:

  1. All API calls require that both the user and application are authenticated and authorized.
  2. After authentication, the session information should be known only by the user, the application, and Facebook.
  3. API calls using this authentication can be used only for operations that read or update user data or perform actions on behalf of the user/app combination. For example, profile.setFBML cannot be used to modify other users' FBML.

[edit] Your Application Settings

Before going through the authentication flow, let's explain some basic terms about an application.

Your application needs to be registered on Facebook. For a Web application that uses JavaScript to call the Facebook Platform API, you need to specify the following settings:

  • Callback URL, which must be set to a URL on your server that hosts the application
  • Application Type, which must be set to Website
  • Canvas Page URL, which must be set to Use iframe

The image below illustrates these settings:
Image:Js_Auth_Model_Figure1.jpg

Facebook provides every application with an API key and a secret key. The API key is public information. The secret key is known by the application developer and Facebook only. For the JavaScript API, the secret key is not used in order to avoid exposing it to users. Instead, the JavaScript API uses a session-based temporary secret.

[edit] Authentication Flow

Applications are accessed through the callback URL (http://www.foo.com/index.htm) directly or through the canvas page URL (http://apps.facebook.com/foo_demo/). In either case, a user's Web browser navigates to http://www.foo.com/index.htm (either through the address bar or through an iframe).

In order to use JavaScript to call the Platform API, the Web page at http://www.foo.com/index.htm should contain a reference to the Facebook JavaScript library.

For demonstration, let's assume that http://www.foo.com/index.htm contains the following codes:

<script src="http://www.facebook.com/js/api_lib/FacebookApi.debug.js" type="text/javascript"></script> <!-- Demo code that use the Facebook API --> <script type="text/javascript"> var api = new FB.ApiClient('161c02792ce62ad5e4de800c1a576cab', '/xd_receiver.htm', null); //require user to login api.requireLogin(function(exception) { // Example of calling API in non-batched mode. //In non-batched mode, a callback function as last argument api.friends_get(function(result, exception) { Debug.assert(!exception); Debug.dump(result, 'friendsResult from non-batch execution '); }); });


When api.RequireLogin() is called, it checks document.URL to look for the query parameter session. Because http://www.foo.com/index.htm does not contain the parameter, the code navigates the browser to http://www.facebook.com/login.php?return_session=1&api_key=<API_KEY>&v=1.0.

When this URL request reaches the Facebook server, it checks whether the user has already logged in and allowed the application access to his or her account. If the user isn't logged in, the app prompts the user to enter his or her user name and password to log in. Likewise, if the user didn't grant the app access already, the app asks the user to give it access. Next, the Facebook server creates a temporary session containing a session key, a session secret, and the session expiration time. It also fetches the callback URL of the application from the Facebook database. It then sends back an HTTP response that tells the browser to navigate to that callback URL with the session query parameter. For our sample application, the HTTP response looks like this:

<html><head><title>Redirecting...</title><meta http-equiv="refresh" content="0;url=http://www.foo.com/index.htm?session=%7B%22session_key%22%3A%2235adb2de1369ecff6d622a43-711562108%22%2C%22uid%22%3A711562108%2C%22expires%22%3A0%2C%22secret%22%3A%22%22%7D" /></head><body><script type="text/javascript"><!-- document.location.href='http://www.foo.com/index.htm?session=%7B%22session_key%22%3A%2235adb2de1369ecff6d622a43-711562108%22%2C%22uid%22%3A711562108%2C%22expires%22%3A0%2C%22secret%22%3A%22%22%7D'//--></script></body></html>


When the user's browser receives the HTTP response, it navigates to http://www.foo.com/index.htm?session=XXX. The JavaScript code in index.htm executes and api.RequireLogin gets called again. This time, the code finds the session parameter in document.URL and stores the specified session information, including the session key and secret. At this point, the authentication process is completed.

There are several important points to consider regarding this process:

  1. Facebook verifies that a valid user is logged in and has given permission to the specified app.
  2. A session is only valid for the specified combination of user and app.
  3. The session created in this process is temporary and can be used only for operations that read or update user data or perform actions on behalf of that user/app combination.
  4. The redirect URL is retrieved from the app's callback URL. For example, if a page on http://www.evil.com navigates the user to http://www.facebook.com/login.php with the app's API key, Facebook still redirects the user to http://www.foo.com/index.htm. Because of cross-domain restrictions in the browser, http://www.evil.com cannot read the session parameter.
reference