Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough

Integrating FBOAuth with Services

Parent Feed: 

Everyone loves the Services module. It allows you to easily create API endpoints for Drupal's core features, permitting you to interact with Drupal from external applications. It also very easily extended.

Among its many default resources, Services offers a user.login method that allows external applications to authenticate via Drupal. I'm going to share a quick snippet that will permit you to extend Services so that it allows your users to login via Facebook (leveraging the FBOauth module).

Start by downloading and enabling Services and Fboauth. Then, create a custom module to house your code. Your module's info file should specify services and fboauth as requirements.


Easy enough. Now let's use Service's hook_services_resources() function to define a new resource.

 'Login a user for a new session via FBOAuth',
    'callback' => 'services_fboauth_connect',
    'args' => array(
      array(
        'name' => 'access_token',
        'type' => 'string',
        'description' => 'A valid Facebook access token',
        'source' => 'data',
        'optional' => FALSE,
      ),
    ),
    // The services module says this about services_access_menu: 
    // "If you think you need it you are almost certainly wrong."
    // But I think that this is one of those rare exceptions.
    'access callback' => 'services_access_menu',
  );

  return $definition;
}
?>

Here, we've defined a new resource type "fboauth." We've also defined a new action for that resource, labeled 'connect'. This will be available at /your_endpoint_path/fboauth/connect.

Now let's define the services_fboauth_connect() callback that makes the magic happen.

uid) {
    // user is already logged in
    return services_error(t('Already logged in as @user.', array('@user' => $user->name)), 406);
  }

  // Include fboauth functions as required.
  module_load_include('inc', 'fboauth', 'includes/fboauth.fboauth');
  $access_token = $data['access_token'];
  $app_id       = variable_get('fboauth_id', '');
  
  // Find Drupal user that corresponds with this Facebook user.
  $fbuser = fboauth_graph_query('me', $access_token);
  $uid = fboauth_uid_load($fbuser->id);
  if ($user = user_load($uid)) {
    if ($user->status) {
      // Much of the login logic was taken from _user_resource_login().
      user_login_finalize();

      $return = new stdClass();
      $return->sessid = session_id();
      $return->session_name = session_name();

      services_remove_user_data($user);

      $return->user = $user;

      return $return;
    }
    else {
      $message = t('The username %name has not been activated or is blocked.', array('%name' => $account->name));
    }
  }
  else {
    $message = t('Error: no Drupal account was found for the specified Facebook user');
  }

  watchdog('services_fboauth', $message);
  return services_error($message, 401);
}
?>

To use this function, your external application must POST a valid 'access_token' to /your_endpoint_path/fboauth/connect. The endpoint will then return a valid session object, identical to the one posted by the default user.login method.

That's all there is to it!

Author: 
Original Post: 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web