Login for Games on Facebook

Overview

When you build a game for to be played on Facebook.com, you're building a web app which will be served inside an iframe container on Facebook.com. Since Facebook only serves games to logged in players, this means that you are guaranteed to have a logged in Facebook user available for authentication.

As such, you should always build Facebook Login support into your game, to provide you with a consistent ID on which to sync and persist game progress, and for implementing the social features that gamers expect in the games they play. If your game exists on multiple platforms, you can use this same ID to synchronise the game state for your players across the devices they use.

This document outlines the various approaches for using Facebook Login and how you can make best use of them in your game.

Authentication Sources

There are a number of ways that a player can authenticate for the first time, and several approaches for verifying identity after the first authentication.

App Center Authentication

When players launch your game via the Play Now button in App Center, they're authing your app for a specific set of permissions as configured in the App Details tab in App Dashboard.

The Play Now button in App Center

Given that a high percentage of players will come to your app via App Center, this will be a common authentication path. To ensure smooth login from App Center, you should configure the set of permissions granted via App Center to match the permissions your game expects on Facebook.com and on mobile.

See the App Center guide for more details.

Authentication on another platform

If your game exists on mobile platforms, and supports Facebook Login in the mobile version, it's possible that some of your players will already be authenticated when they come to play your game on Facebook.com. It's important to make sure that the version of your game on Facebook.com expects the same set of permissions as your mobile game.

Detecting Login Status

As described above, players will come to your game in either a logged in or not logged in state, depending on whether they've authed your game in the past, either by playing your game on Facebook previously, via App Center, or via a mobile version of your game.

You can detect whether a player has previously logged into your game in one of two ways:

  • Client-side, using the JS SDK FB.getLoginStatus() method
  • Server-side, by decoding a signed_request

Using the Facebook SDK for JavaScript

By calling FB.getLoginStatus() on document load, you can ensure that a player is immediately logged in when they load the game. You can then use FB.api() to access the player's game state via their user ID, and to retrieve information used for personalization, such as the player's name, profile picture and friend list.

FB.getLoginStatus(function(response) {
  if (response.status === 'connected') {
    // the user is logged in and has authenticated your
    // app, and response.authResponse supplies
    // the user's ID, a valid access token, a signed
    // request, and the time the access token 
    // and signed request each expire
    var uid = response.authResponse.userID;
    var accessToken = response.authResponse.accessToken;
  } else if (response.status === 'not_authorized') {
    // the user is logged in to Facebook, 
    // but has not authenticated your app
  } else {
    // the user isn't logged in to Facebook.
  }
 }); 

If the player hasn't logged in, you can call FB.login(...) to show a modal version of the login dialog on top of your game's initial screen. The callback for this dialog should be the same method call that you use when calling FB.getLoginStatus

Using a Signed Request

When your game is loaded on Facebook.com, a HTTP POST request is made to your specified Facebook Web Games URL. This POST request will contain some parameters, including the signed_request parameter which you can use for authorisation.

The signed_request is base64url encoded and signed with an HMAC version of your App Secret, based on the OAuth 2.0 spec.

What this means is that when it is POSTed to your app, you will need to parse and verify it before it can be used. This is performed in three steps:

  1. Split the signed request into two parts delineated by a '.' character (eg. 238fsdfsd.oijdoifjsidf899)
  2. Decode the first part - the encoded signature - from base64url
  3. Decode the second part - the payload - from base64url and then decode the resultant JSON object

These steps are possible in any modern programming language. Below is an example in PHP:

function parse_signed_request($signed_request) {
  list($encoded_sig, $payload) = explode('.', $signed_request, 2); 

  $secret = "appsecret"; // Use your app secret here

  // decode the data
  $sig = base64_url_decode($encoded_sig);
  $data = json_decode(base64_url_decode($payload), true);

  // confirm the signature
  $expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
  if ($sig !== $expected_sig) {
    error_log('Bad Signed JSON signature!');
    return null;
  }

  return $data;
}

function base64_url_decode($input) {
  return base64_decode(strtr($input, '-_', '+/'));
}

This will produce a JSON object that looks something like this:

{
   "oauth_token": "{user-access-token}",
   "algorithm": "HMAC-SHA256",
   "expires": 1291840400,
   "issued_at": 1291836800,
   "user_id": "218471"
}

By parsing the signed_request parameter, you'll be able to detect whether the current player has authenticated your game. If they have, the signed_request will contain the player's user ID, which you can use for retrieving personalization information and game state. You can exchange this signed_request for an access token, and use that to access the Graph API for deeper personalisation.

If the player hasn't authenticated your game, you can instruct the browser to redirect to the Facebook OAuth endpoint, so the player can authenticate the game. See Server-side Login via Oauth for more details

First-time Authentication

The first time a player comes to your game, you should invite them to authenticate by presenting the Login Dialog. You can do this in two different ways

  1. Client-side login via Javascript
  2. Server-side login via OAuth Redirect.

Client-side Login via Javascript SDK is the recommended login flow for authentication. Historically, [Server-side Login via OAuth] been popular amongst developers, but client-side login gives developer extra control of the login flow. For example, developers can show simple game graphics before launching a login dialog and after canceling the dialog.

Happy Acres, which uses a custom background on login

Client-side Login via JS SDK

Unique to games on Facebook, the JavaScript version of the Login Dialog will be triggered in async mode within the iframe. This means that it appears as a modal popup over the rest of the game contents, rather than as a separate popup browser window.

This is important, as it means that the dialog can be invoked directly from code, and not as part of a UI event, without being blocked by a browser's popup blocking detection methods.

As a result, you can use FB.getLoginStatus() to check if the current player has authenticated your game before, and if not, immediately display the Login Dialog on top of your game content by calling FB.login(), without needing to show a 'Log In' button.

See below for an example:

// Place following code after FB.init call.

function onLogin(response) {
  if (response.status == 'connected') {
    FB.api('/me?fields=first_name', function(data) {
      var welcomeBlock = document.getElementById('fb-welcome');
      welcomeBlock.innerHTML = 'Hello, ' + data.first_name + '!';
    });
  }
}

FB.getLoginStatus(function(response) {
  // Check login status on load, and if the user is
  // already logged in, go directly to the welcome message.
  if (response.status == 'connected') {
    onLogin(response);
  } else {
    // Otherwise, show Login dialog first.
    FB.login(function(response) {
      onLogin(response);
    }, {scope: 'user_friends, email'});
  }
});

Server-side Login via OAuth

If you prefer to handle login verification on your server, you can use Server-side login via OAuth. With this flow, you'll redirect the player's browser to the OAuth Login Dialog to authenticate:

https://www.facebook.com/{version}/dialog/oauth?
    client_id={app-id}&
    redirect_uri={redirect-uri}&
    scope={permissions}

The dialog will redirect back to a URL you control, which is usually your Facebook Web Games URL. Once this round-trip completes, the HTTP POST call to your Facebook Web Games URL will contain a signed_request parameter, which you can use for personalization.

Please read this doc for full implementation details, or see below for a basic example:

<?php
    require 'facebook.php';

    $app_id = 'APP_ID';
    $app_secret = 'APP_SECRET';
    $app_namespace = 'APP_NAMESPACE';
    $app_url = 'https://apps.facebook.com/' . $app_namespace . '/';
    $scope = 'email,publish_actions';

    // Init the Facebook SDK
    $facebook = new Facebook(array(
         'appId'  => $app_id,
         'secret' => $app_secret,
));

// Get the current user
$user = $facebook->getUser();

// If the user has not installed the app, redirect them to the Login Dialog
if (!$user) {
        $loginUrl = $facebook->getLoginUrl(array(
        'scope' => $scope,
        'redirect_uri' => $app_url,
        ));

        print('<script> top.location.href=\'' . $loginUrl . '\'</script>');
}
?>

You must do this redirect in JS and target the top frame via top.location, otherwise the redirect won't work.

Next Steps

Whichever method you choose to use for login, having a real identity in your game will help you build great social features that will help with retention and distribution of your game.

Login is the first step towards many of these features, and you can build them using the products below:

Take a look at the Best Practices for Games on Facebook for more tips on using Facebook Login effectively in your game.