Demonstrating OAuth 2.0 using Facebook's Graph API

Introduction

OAuth 2.0 is regarded as the industry-standard protocol for authorization. It works by delegating user authentication to the service that hosts the user account (trusted identity provider), and authorizing third-party applications to access the user account.

This post focuses on implementing the OAuth flow to authorize a Facebook app to access user data.

repo@github

FacebookController

OAuth Roles

The Resource Server and Authorization Server roles can be (and usually is) combined to form an API that fulfills both service roles.

Protocol Flow

OAuth 2.0 Flow High level overview of OAuth protocol flow

  1. The application requests authorization to access protected resources from the User.
  2. When the user authorizes the request, the application receives an authorization grant. (The grant types will be discussed briefly later on)
  3. The application requests for an Access Token from the authorization server (API) in exchange for the authorization grant. (Application identity details too are sent along with the authorization grant to the API token endpoint)
  4. The authorization server (API) issues an Access Token when both application identity and authorization grant are validated.
  5. The Application requests the protected resource from the API while presenting the Access Token for authentication.
  6. If the token is valid, the resource endpoint serves the resource to the application.

Application Registration

app_registration_fb Application Registration fallout on Facebook Developers

Before using OAuth with an application, the application must be first registered with the service.

Client ID and Client Secret

Once the application is registered, the service will issue "client credentials". It consists of a client identifier and a client secret. (A username-and-password-like combination) The Client ID is a publicly exposed string that is used by the service API to identify the application. The Client Secret is used to authenticate the identity of the application to the service API when the application requests to access a user's account. It must be kept private between the application and the API. Implementing client side code with the Client Secret in plain is a huge security risk.

Callback URLs

fb_callbacks Callback URLs for the application

Redirect URLs must be pre-configured into the service before exposing them via the client code. These will determine where a user is redirected upon the authorization result.

Authorization Grant

OAuth 2.0 defines four grant types, each of which is useful in different cases:

Authorization Code Grant Type

The authorization code grant type is the most commonly used because it is optimized for server-side applications. Because the server-side source code is not publicly exposed, Client Secret confidentiality can be maintained.

Authorization Code Link

fb_login

The user is prompted to click on a button or link that resembles the following format.

https://www.facebook.com/v2.12/dialog/oauth?client_id=161640204541883&state=2081c5c62987cf1a760e3833295f3ea2&response_type=code&sdk=php-sdk-5.6.2&redirect_uri=https%3A%2F%2Fwww.oauthtest.lk%2Ffbcallback&scope=email%2Cpublic_profile%2Cuser_posts%2Cuser_friends%2Cpublish_actions

The link components are as follows.

    public function show()
    {
        $fb = new Facebook(
            'app_id' => env('FB_APP_ID'),
            'app_secret' => env('FB_APP_SECRET'),
            'default_graph_version' => env('API_VERSION'),
        ]);
        $helper = $fb->getRedirectLoginHelper();
        $permissions = ['email', 'public_profile', 'user_posts', 'user_friends', 'publish_actions',];
        $loginUrl = $helper->getLoginUrl('https://www.oauthtest.lk/fbcallback', $permissions);
        $url = htmlspecialchars($loginUrl);
        return view('index')->with('url', $url);
    }

User Authorizes the application

When the user clicks the link, the user-agent (browser) is redirected to the identity service (i.e. Facebook) to authenticate the user's identity. The user must login to the service if they're not logged in already.

authentication

Application Receives Authorization Code

When the user authorizes the application, the service redirects the user-agent to the application redirect URL, which was specified during the client registration, along with an authorization code and the state parameter. The redirect would look something like this.

callback_img

Application Requests Access Token

The application requests an access token from the API, by passing the authorization code along with authentication details, including the client secret, to the API token endpoint.

GET https://graph.facebook.com/v2.12/oauth/access_token? client_id={app-id} &redirect_uri={redirect-uri} &client_secret={app-secret} &code={code-parameter} 

Application Receives Access Token

If the authorization is valid, the API will send a response containing the access token  to the application.

access_token

     $helper = $fb->getRedirectLoginHelper();
     $_SESSION['FBRLH_state'] = $_GET['state'];
     try {
        $accessToken = $helper->getAccessToken(); //the SDK does a post to the token endpoint
        } catch (FacebookSDKException $e) {
            echo 'Facebook SDK returned an error: ' . $e->getMessage();
            exit;
        }