Consuming APIs using OAuth 2.0

This post will guide you an introduction to OAuth 2.0 and will guide you on how you can implement the OAuth flow in order to consume the Twitter API from your application.

Dinuksha Ishwari
Oct 8, 2018 · 9 min read

What is OAuth 2.0?

OAuth 2.0 is creating a lot of hype in the web service and software industry around the globe. And we often hear many applications and services adapting to it.

Simply put,

Nowadays web applications are used very widely for almost every task. But it is difficult to remember separate credentials to each and every application. Also, there can be instances where an application requires to communicate with other applications on behalf of the user. These are the basic problems OAuth tries to address.

Before diving deeper into OAuth 2.0, it is important to understand what the following keywords mean.

Authentication — validating if the person is who he says he is.
Authorization — what actions a person is allowed to perform when he/she has been authenticated.

OAuth 2.0 provides,

  • Federated Identity — Allowing users to log in to an application with another account.
  • Delegated Authority — Allowing another service to access resources on another service on behalf of the user.

OAuth 2.0 alone specifies only authorization. In order to fulfill the Authentication requirement, it combines with OpenID Connect.

The Flow

Before OAuth 2.0, if an application wants to access your data from another application, you have to provide your account credentials, from which the data is to be accessed, to the application who wants to access the data. For example, if an application wants to suggest you your friends from Facebook you will have to provide your credentials of Facebook and then the said application will impersonate you and handle your Facebook account. Not to forget, this gives them full control of the account. That application may even store your credentials. In a time where data security is crucial, we cannot simply trust the applications. Therefore they needed a protocol to do this without compromising user’s data safety.

OAuth 2.0 overcomes this. If an application, let's say its called ‘Sample App’, wants to access your friend list, Sample App will ask if you can permit them to access your Facebook friend list. If you grant permission, you will be redirected to a page prompt by Facebook informing you that Sample App wants to access your friend list and asking you if you would want to give your consent to do so. If you allow, Facebook will provide the relevant details to ‘Sample App’. This is how OAuth 2.0 works very briefly.

How it works

There are five types of grants specified in the OAuth 2.0 specification. Namely,

  • Authorization grant
  • Implicit grant
  • Resource owner credentials grant
  • Client credentials grant
  • Refresh token grant

Endpoints

  • Redirection Endpoint — This is provided by the Client Application to the service provider. The service provider will send the access tokens etc to this endpoint.
  • Authorization Endpoint — This is the endpoint the Client Application should use to initiate the Authorization process.
  • Token Endpoint — This is the endpoint the Client Application should use to initiate Token flow.

1. Authorization Grant Flow

1) The application (Client) sends an authorization request to the Auth Server (Authorization Endpoint).

2) Auth Server requests the user for his/her consent for the Application (Client) to access the claims it requests.

3) If the user grants consent, Auth Server provides an Authorization Code grant to the Client Application. (Redirection Endpoint)

4) Client Application sends an Access Token Request to the Auth Server along with the Authorization Code provided previously. (Token Endpoint)

5) Auth Server provides the Access Token (which expires after a specified time period) and Refresh Token to the Client Application to access the claims requested before.

6) If the Access Token expires, Client Application sends a request to the Auth Server (Token Endpoint) along with the refresh token and request for a new Access Token.

2. Implicit Grant

This flow is implemented by applications that run on the Client side (i.e: Javascript).

1) This flow will follow the same 1) and 2) steps in Authorization Grant flow but in the Authorization Request it will mention ‘token’ as the response type, whereas in the previous flow it was ‘code’.

2) If the user grants consent, Auth Server redirects the user-agent to the redirect URI provided by the Client Application that contains a URI fragment containing the access token.

3) User-agent follows the redirect URI retaining the access token

4) The application sends a script to the user agent that can extract the access token.

5) User-agent runs the script and returns the token to the Application.

3. Password Credentials Flow

In this flow, the user will provide his/her credentials directly to the Client Application and it will produce these credentials and request an Access Token from the Auth Server.

4. Client Credentials

The client application sends its credentials (Client ID, Client Secret) in order to obtain an access token and authorize itself to access its own account.

Out of these, the most commonly used ones are 1) and 2).

This specification allows developers to worry less about the authentication and authorization and worry solely about the application logic implementation.

Now, let’s implement a sample application that uses OAuth 2.0 Authorization Grant flow to allow users to browse their Gmail inbox.

Step 1: Create an application

Go to https://console.developers.google.com/ as select ‘Select a project’ as shown below.

From the prompt that opens up, select ‘New Project’.

Fill the below form with your application name and submit.

You can see the created application as below.

Step 2: Generate credentials

Select ‘Gmail API’ from the above window and you will be redirected to the below page. Click on ‘Enable’.

Now the Gmail API is enabled for our application. In order to access this using OAuth, we need an AppID and App Secret. For that, select ‘Create Credentials’ from the below page.

You can fill out the below data related to your application and generate the credentials.

Creating a Client ID

You can view the added credentials as below.

If you select the application from the above, you can find the Client ID and Secret both which we are going to need to implement the OAuth flow.

Now let’s look at our application can consume this. The sample application here is a spring boot application.

Step 3: Consuming the API — Obtaining the Authorization Code

First, the user must be redirected to Google’s sign in page to authorize our application. In order to do that, our application must redirect the users to the Authorization Endpoint. Google’s Authorization Endpoint (https://accounts.google.com/o/oauth2/auth) expects an endpoint like below.

GET https://accounts.google.com/o/oauth2/auth?redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fcallback&prompt=consent&response_type=code&client_id=xxxxxxxxxxxxx&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.readonly&access_type=offline&state=1234

It contains the following as query parameters.

redirect_uri — Determines where the API server redirects the user after the user completes the authorization flow. This must match what you specified as the redirect_uri in the API console.

response_type — Specifies the response type expected. Since this is the Authorization Code Grant, response type will be code.

client_id — The client ID for your application that we generated previously.

scope — A space-delimited list of scopes that identify the resources that your application could access on the user’s behalf. These values inform the consent screen that Google displays to the user. You can find the appropriate scope for your application here.

prompt — A space-delimited, case-sensitive list of prompts to present the user. If you don’t specify this parameter, the user will be prompted only the first time your app requests access. Since we need the user to login, and provide consent for our application to access the scope specified, we will use ‘consent’.

access_type — Indicates whether your application can refresh access tokens when the user is not present at the browser.

state —Additionally, you can add this parameter too. This contains certain states that need to be passed between request. Often, this is used to pass CSRF tokens.

This endpoint is implemented as follows in index() method,

AuthController

When the user is redirected to the Authorization Endpoint, following page will be prompted by Google.

User Login Page
User Consent Page

After the user grants consent, the redirect_uri we specified previously will receive the authorization code. Typically this code values are short lived.

We need to handle how the callback endpoint (what we specified as the redirect_uri) extract this code and request for the token. This endpoint is implemented in the AuthController by the callback() method.

Step 4: Consuming the API — Obtaining the Access Token

You will be redirected to the redirect_url you specified before as follows,

In the callback() method, which implements the /callback endpoint, it extracts the code from the query param and the state param that we added previously will be a query param as well. Next, we will create the token request to POST https://www.googleapis.com/oauth2/v3/token specifying the below parameters in the body as URLEncoded form data.

code — Code received by Google OAuth

client_id — Client ID, same as previous

client_secret — Client Secret obtained from the API console

redirect_uri — Must be the same as before, and must match the URL specified in the API console

grant_type — This value must be authorization_code

Once this call is completed, you will receive the access token, refresh token, expiry time etc as a json response.

{
"access_token":"1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in":3920,
"token_type":"Bearer",
"refresh_token":"1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

Here, the expiry time is specified for the access token. Once it is expired, refresh token can be used to obtain a new access token. If the refresh token is lost, user will have to go through the flow again from the consent page to obtain an access token.

Once, this is received, we will safely store the access token and the refresh token. For demo purpose, I will only store the access token against user session.

Step 5: Consuming the API with the Access Token

Next, let’s look at how we can use this access token to query Google APIs.

In order to browse any Google API for user data, we have to add the Access Token obtained in the Authorization header of the request.

Eq:

Authorization: Bearer xxxxxxxxxxxxxxx

In Java, you can simply write a method like below to execute GET requests.

public static String executeGetWithAuthorization(String targetURL, String accessToken) throws IOException {
HttpClient client = HttpClientBuilder.create().build();
HttpGet httpGet = new HttpGet(targetURL);
httpGet.addHeader("Authorization", "Bearer "+ accessToken);
ResponseHandler<String> handler = new BasicResponseHandler();
HttpResponse response = client.execute(httpGet);
return handler.handleResponse(response);
}

Then, I have implemented a service to consume the APIs as below. For convenience, I have commented the endpoints used.

Once, the access token is received user will be redirected to our home page and the above calls will be executed to retrieve user data as below.

Home page

You can refer Gmail API documentation to learn more about the endpoints and Google OAuth documentation for more details about the OAuth flow. The full implementation of the sample application can be found here.