Yasser Shohoud

Platform Updates: Operation Developer Love

By Yasser Shohoud - Friday at 6:00pm

Handling invalidated access tokens

Last week, we reminded you how you should handle invalid access tokens. This is an important concept to understand as there are several legitimate reasons an access token can become invalid such as:

  • its expiration time was reached
  • a user changed their password
  • a user deauthorized your application
  • a user logged out of Facebook
  • we invalidated it for security reasons

Even if you have the offline_access permission from the user, your token can still be invalidated. You should ensure you application is built to handle these scenarios.

New PHP SDK

Today we upgraded the PHP SDK to version 3.0.0. Be sure to read our blog post which explains the changes as well as when you should consider upgrading. Version 2 of the PHP SDK will no longer work come September 1st as we will be requiring all apps to use the new OAuth flows.

Client-side re-authentication flow

A couple weeks ago we introduced a server-side way for you to force a user to re-enter their password to confirm their identity (e.g. before making a purchase on a shared computer). We now have a way to perform re-authentication on the client side as well. To get started, check out the example below or see the documentation.

<html>
<head></head>
<body>
<div id="fb-root"></div>
<button id="fb-login" onclick="login()">Login</button>
<script>
  var button = document.getElementById('fb-login');

  // For help with AJAX, see http://www.w3schools.com/Ajax/Default.Asp
  function checkNonce(access_token) {
    var xmlhttp;
    if (window.XMLHttpRequest)
      {// code for IE7+, Firefox, Chrome, Opera, Safari
      xmlhttp=new XMLHttpRequest();
      }
    else
      {// code for IE6, IE5
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
      }
    xmlhttp.onreadystatechange=function() {
      if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
          if (xmlhttp.responseText == 1) {
            console.log('The user has been successfully ' +
                               're-authenticated.');
          } else {
            console.log('The nonce has been used before. ' +
                               'Re-authentication failed.');
          }
        }
    }
    xmlhttp.open('POST','checkNonce.php',true);
    xmlhttp.setRequestHeader('Content-type',
      'application/x-www-form-urlencoded');
    xmlhttp.send('access_token=' + access_token);
  }

  function login(){
    FB.login(function(response) {
      if (response) {
        console.log('Login success. Checking auth_nonce...');
        checkNonce(response.session.access_token);
      } else {
          console.log('Login cancelled.')
      }
    }, { auth_type: 'reauthenticate', auth_nonce: 'abcd1234' });
  }

  window.fbAsyncInit = function() {
    FB.init({appId: 'YOUR_APP_ID', status: true, cookie: true,
             xfbml: true});
    FB.getLoginStatus(function(response) {
      if (response.session) {
        button.innerHTML = 'Re-Authenticate';
        console.log('User is logged in.');
      } else {
          console.log('User is not logged in.');
      }
    });
  };
  (function() {
    var e = document.createElement('script'); e.async = true;
    e.src = document.location.protocol +
      '//connect.facebook.net/en_US/all.js';
    document.getElementById('fb-root').appendChild(e);
  }());
</script>
</body>
</html>

checkNonce.php

<?php

    $access_token = $_REQUEST['access_token'];
    $graph_url = 'https://graph.facebook.com/oauth/access_token_info?'
        . 'client_id=YOUR_APP_ID&access;_token=' . $access_token;
    $access_token_info = json_decode(file_get_contents($graph_url));

    function nonceHasBeenUsed($auth_nonce) {
        // Here you would check your database to see if the nonce
        // has been used before. For the sake of this example, we'll
        // just assume the answer is "no".
        return false;
    }

    if (nonceHasBeenUsed($access_token_info->auth_nonce) != true) {
        echo '1';
     } else {
        echo '0';
     }
?>

Old Insights Dashboard

As previously announced, we will remove the old version of the Insights dashboard on Tuesday as all the metrics that were previously available are now available in the new Insights dashboard.

Improving Docs

Documentation activity for the past 7 days:

Fixing Bugs

Bugzilla activity for the past 7 days:

  • 195 new bugs were reported
  • 67 bugs were reproducible and accepted (after duplicates removed)
  • 16 bugs were fixed (13 previously reported bugs and 3 new bugs)
  • As of today, there are 1,287 open bugs in Bugzilla (up 3 from last week)

Forum Activity

Developer Forum activity for the past 7 days:

  • 480 New Topics Created
  • 243 New Topics received a reply
  • Of those 243, 21 were replied to by a Facebook Employee
  • Of those 243, 35 were replied to by a community moderator

Yasser Shohoud, a Partner Engineer on the Developer Relations team, is looking forward to seeing how you use the re-authentication feature to create safe, seamless user authentication flows.

Jerry Cain

Upgrade to PHP SDK v3.0.0

By Jerry Cain - Friday at 4:40pm

As part of our Developer Roadmap update requiring all apps to use OAuth 2.0 and HTTPS, we planned to make available an updated PHP SDK that uses OAuth 2.0. Although we originally planned to release the PHP SDK on July 1st, we moved fast and completed the update to version 3.0.0. This SDK is now available for download on GitHub.

The new PHP SDK (v3.0.0) is a major upgrade to the older one (v2.2.x):

  • Uses OAuth authentication flows instead of our legacy authentication flow
  • Consists of two classes. The first (class BaseFacebook) maintains the core of the upgrade, and the second one (class Facebook) is a small subclass that uses PHP sessions to store the user id and access token.

If you’re currently using the PHP SDK (v2.2.x) for authentication, you will recall that the login code looked like this:

$facebook = new Facebook(…);
$session = $facebook->getSession();
if ($session) {
  // proceed knowing you have a valid user session
} else {
  // proceed knowing you require user login and/or authentication
}

The login code is now:

$facebook = new Facebook(…);
$user = $facebook->getUser();
if ($user) {
  // proceed knowing you have a logged in user who's authenticated
} else {
  // proceed knowing you require user login and/or authentication
}

Download the full example here. The red text below indicates changes from the earlier example.php (v2.2.x):

<?php

require 'facebook.php';

// Create our application instance
// (replace this with your appId and secret).
$facebook = new Facebook(array(
  'appId'  => 'YOUR_APP_ID',
  'secret' => 'YOUR_APP_SECRET',
));

// Get User ID
$user = $facebook->getUser();

// We may or may not have this data based 
// on whether the user is logged in.
// If we have a $user id here, it means we know 
// the user is logged into
// Facebook, but we don’t know if the access token is valid. An access
// token is invalid if the user logged out of Facebook.

if ($user) {
  try {
    // Proceed knowing you have a logged in user who's authenticated.
    $user_profile = $facebook->api('/me');
  } catch (FacebookApiException $e) {
    error_log($e);
    $user = null;
  }
}

// Login or logout url will be needed depending on current user state.
if ($user) {
  $logoutUrl = $facebook->getLogoutUrl();
} else {
  $loginUrl = $facebook->getLoginUrl();
}

// This call will always work since we are fetching public data.
$naitik = $facebook->api('/naitik');

?>
<!doctype html>
<html xmlns:fb="http://www.facebook.com/2008/fbml">
  <head>
    <title>php-sdk</title>
    <style>
      body {
        font-family: 'Lucida Grande', Verdana, Arial, sans-serif;
      }
      h1 a {
        text-decoration: none;
        color: #3b5998;
      }
      h1 a:hover {
        text-decoration: underline;
      }
    </style>
  </head>
  <body>
    <h1>php-sdk</h1>

    <?php if ($user): ?>
      <a href="<?php echo $logoutUrl; ?>">Logout</a>
    <?php else: ?>
      <div>
        Login using OAuth 2.0 handled by the PHP SDK:
        <a href="<?php echo $loginUrl; ?>">Login with Facebook</a>
      </div>
    <?php endif ?>

    <h3>PHP Session</h3>
    <pre><?php print_r($_SESSION); ?></pre>

    <?php if ($user): ?>
      <h3>You</h3>
      <img src="https://graph.facebook.com/<?php echo $user; ?>/picture">

      <h3>Your User Object (/me)</h3>
      <pre><?php print_r($user_profile); ?></pre>
    <?php else: ?>
      <strong><em>You are not Connected.</em></strong>
    <?php endif ?>

    <h3>Public profile of Naitik</h3>
    <img src="https://graph.facebook.com/naitik/picture">
    <?php echo $naitik['name']; ?>
  </body>
</html>

When to upgrade

If you are only using the PHP SDK for authentication, please upgrade now. If you are using the JavaScript SDK for login in conjunction with the PHP SDK, you will want to wait for the JavaScript SDK upgrade (coming in 4 weeks). Version 3.0.0 of the PHP SDK won’t cooperate with the current JavaScript SDK due to the cookie format changing.

Below is a table to help you remember when to begin upgrading:

Login FlowUpgrade
PHP SDK for login and API callsNow
JS SDK for login and PHP SDK for API calls4 weeks
JS SDK for login and API calls4 weeks

To learn more about the OAuth 2.0 flow and how to implement OAuth with CSRF protection, please read our Authentication Guide. All apps must utilize the new OAuth flows by September 1.

If you have any questions or feedback on this release, please leave them in the Comments Box below.

Matt Stone Trainer

Improvements to the Preferred Developer Consultant Program

By Matt Stone Trainer - Thursday at 9:15am

We introduced the Preferred Developer Consultant (PDC) program in December 2009 to connect companies and brands to the resources they need to build with Facebook products and technologies.

This February, we opened up a new round of submissions for the PDC program. As businesses across the world look to get smarter about integrating Facebook, we seek to ensure that the PDC program continues to meet these needs everywhere that people use Facebook. We’ve selected 25 new companies, including 13 internationally-based companies, to join the PDC program. Our 90 PDCs now span across 170 offices and dozens of countries, with 67 offices outside of the US. You can visit the directory to see the full list of Preferred Developers. Please join us in welcoming to the program:

  • AdNectar
  • ADTELLIGENCE GmbH
  • Affinitive
  • Altodot
  • Bazaarvoice
  • Brainsonic
  • Conversocial
  • Dudes Division
  • Emakina
  • Extole, Inc.
  • Fennek & Friends
  • FPT Corporation
  • Jung von Matt/Neckar
  • MakeMeReach
  • Mediatonic Ltd
  • Mobile Interactive Group
  • OpenGraphy
  • PowerReviews
  • Pure
  • Shoutlet, Inc.
  • The Gifts Project
  • thisMoment, Inc.
  • Tigerlily
  • Utopic Farm
  • Varsity Outreach

As this program expands across the globe, finding a Preferred Developer in your local area becomes more important. Today we’re proud to announce our revamped Preferred Developer Lookup Tool. Designed and built by Gamaroff Digital, a PDC, the tool allows you to look up PDCs by expertise, location, and any keyword. It’s an excellent way to quickly locate the Preferred Developers that can best serve your needs.

What separates a PDC from most other development firms is the ability to understand social mechanics and technical possibilities on Platform. We’re excited to see the vibrant ecosystem of development, especially as this space of social web integrations expands to become a central aspect of every business and market worldwide.

For more information about the PDC program, including case studies and information on applying to be a PDC, please visit our PDC directory.

Matt wants to see more companies with socially designed products.

Zhen Fang

Platform Updates: Operation Developer Love

By Zhen Fang - Friday, May 13, 2011 at 10:15pm

This week, we announced an update to our Developer Roadmap that outlines a plan requiring all apps to migrate to OAuth 2.0, process the signed_request parameter, and obtain an SSL certificate by October 1. We also added two frequently requested How-To guides.

Subscribing to comment threads in the Comments Box

We added the ability to subscribe and unsubscribe from specific comment threads in the Comments Box. If you are interested in a particular part of the conversation, just click the subscribe link, and you'll receive a notification when others reply on thread. Similarly, you can unsubscribe to stop the notifications.

Like Story Feedback now available in Insights

Last month we expanded the story size that is shown when a user Likes a page on your site. We've now added a "Like Story Feedback" dashboard to Insights for your website. This dashboard shows you engagement data such as how many users liked and commented on these stories:

Using this data you can work on generating more interesting stories to fuel the conversation around your content.

API access to Send button metrics

You can now query the Graph API and the Insights FQL table for metrics on Send button activity. When a user engages with the Send button, one or more of the following sequence of actions occurs: the user views the button, then clicks on it, the receiver then views the item in their Messages, and clicks on it. These actions correspond to the following metrics that can be requested via the Graph API or the FQL table:

  • domain_widget_send_views
  • domain_widget_send_clicks
  • domain_widget_send_inbox_views
  • domain_widget_send_inbox_clicks

Each of these metrics is aggregated based on a domain claimed by your application. The FQL Insights documentation contains further details and the list of all available metrics. Here is some example code to retrieve the number of Send button views for a domain for the last three days (the default, see docs for other options):

<?php

  $app_id = "YOUR_APP_ID";
  $app_secret = "YOUR_APP_SECRET";
  $app_domain = "YOUR_APP_DOMAIN"; // e.g. developers.facebook.com

  // First, get a valid access token for the app
  $token_url = "https://graph.facebook.com/oauth/access_token?" .
    "client_id=" . $app_id .
    "&client;_secret=" . $app_secret .
    "&grant;_type=client_credentials";

  $app_access_token = file_get_contents($token_url);

  // Query the Graph API for the send views
  $graph_url="https://graph.facebook.com/insights/"
    . "domain_widget_send_views?"
    . "domain=" . $app_domain . "&"
    . $app_access_token;

  $response = file_get_contents($graph_url);
    
  // Use the results
  echo "<pre>";
  echo print_r(json_decode($response));
  echo "</pre>";

?>

Reference Documentation

As part of Operation Developer Love, we continue to improve our documentation. This week we updated the Album reference documentation for the Graph API. We plan to update the other Graph API reference docs based on this "template", so please let us know in the comments what you think about it. We will be adding information about errors relevant to the Graph API soon.

Improving Docs

Documentation activity for the past 7 days:

Fixing Bugs


Bugzilla activity for the past 7 days:

  • 181 new bugs were reported
  • 30 bugs were reproducible and accepted (after duplicates removed)
  • 17 bugs were fixed (15 previously reported bugs and 2 new bugs)
  • As of today, there are 1,284 open bugs in Bugzilla (up 62 from last week)
Forum Activity


Developer Forum activity for the past 7 days:

  • 511 New Topics Created
  • 239 New Topics received a reply
  • Of those 239, 32 were replied to by a Facebook Employee
  • Of those 239, 51 were replied to by a community moderator

Zhen Fang, on the Developer Relations team, wants to see metrics of how many people sent this post to a friend with the Send button.