Monday, October 8, 2018

A web application that consumes the service of an OAuth Authorization Server and an OAuth Resource Server


OAuth 2.0

OAuth 2.0 logo
OAuth 2.0 is the industry-standard protocol for authorization. OAuth 2.0 supersedes the work done on the original OAuth protocol created in 2006. OAuth 2.0 focuses on client developer simplicity while providing specific authorization flows for web applications, desktop applications, mobile phones, and living room devices.
The following section will guide you to implement a web application that consumes the service of an OAuth Authorization Server and an OAuth Resource Server.
You can implement a Login form with Google feature in your web application using its API. 

Creating a Google App

The first step would be to create a Google App :
  • Go to Google API Console
  • If you have not created a project, create a project by clicking "Select a project" (at the top), and then clicking on the "+" button in the dialogbox. In the next screen enter your project name, and agree with T&C.
  • After the project is created, select the created project from the top dropdown.
  • Click the Library tab on the left. Search for "Google+ API" and enable it.
    By enabling "Google+ API", your Google application can get user information such as id, name, picture, email etc.
  • Now click on Credentials tab on the left. In the next screen click on "OAuth consent screen". Fill out the mandatory fields. Save it.
  • Now click on the "Credentials" tab (just beside "OAuth consent screen"). In the screen, click on "Create credentials". Choose "OAuth Client ID" as the type.
  • In the next screen fill out the name. The Application type should be "Web application"
  • Add a redirect url in the section Authorised redirect URIs. This url should point to your redirect url script. (gauth.php in the attached codes). You can add a localhost url if you want.
    Example of redirect url can be :
    http://website.com/gauth.php
    http://website.com/folder/gauth.php
    http://localhost/folder-name/gauth.php
  • You can leave out Authorised JavaScript origins as blank. Click on the Create button.
  • On success you will get the App Client ID and App Secret. Save those as they will be required later.

Basic Understanding of the Login Process


Google implements OAuth2.0 for the login process. Google has done all the hard work and adding the login API to your code is fairly simple.
  1. You place a link in your HTML code that will redirect to Google's servers for login (called the OAuth login url).
  2. You also provide a redirect url, Google will redirect the user to this url after he does the login. Google will also pass an authorization code to this redirect url.
  3. It is in this redirect url script that you must use the passed authorization code (which is available as a GET parameter). This authorization code can be exchanged for an access token from Google (you have to implement an API call to get the access token from the authorization code).
  4. You can then use the access token to get user information such as id, name, picture, email etc.

Step 1 : Save the App Client ID and Client Secret


Use a settings.php file to save Client ID, Client Secret and Redirect Url
<?php

/* Google App Client Id */
define('CLIENT_ID', 'xxxxxxxxxxxxxxxxxxxx');

/* Google App Client Secret */
define('CLIENT_SECRET', 'xxxxxxxxxxxxxxxxxxxx');

/* Google App Redirect Url */
define('CLIENT_REDIRECT_URL', 'xxxxxxxxxxxxxxxxxxxx');

?>

Step 2 : Add the Link in your code


Add the link to Google OAuth login url in your HTML code. If there is a need you can use PHP header function or Javascript document.location also to redirect to the Google login url.
<?php require_once('settings.php'); $login_url = 'https://accounts.google.com/o/oauth2/v2/auth?scope=' . urlencode('https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/plus.me') . '&redirect_uri=' . urlencode(CLIENT_REDIRECT_URL) . '&response_type=code&client_id=' . CLIENT_ID . '&access_type=online'; ?> <html> <head>....</head> <body> ..... <a href="<?= $login_url ?>">Login with Google</a> ..... </body> </html>
The login url is basically https://accounts.google.com/o/oauth2/v2/auth with five parameters :
  • scope : Scope is basically what you are looking to do or get from the user. Google provides a scope for each of its API services. For just the login and getting user information (including email) you need 3 scopes —
    i) https://www.googleapis.com/auth/userinfo.profile
    ii) https://www.googleapis.com/auth/userinfo.email
    iii) https://www.googleapis.com/auth/plus.me
  • redirect_uri : Your redirect url
  • response_type : Set it to the default value of "code"
  • client_id : Your Google App Client ID
  • access_type : Set it to "online"
Clicking on this link will redirect the user to Google where he does the login. After login Google redirects the user to the redirect url that you have provided. The redirect url script will handle the next steps.

Step 3 : Preparing the Redirect Url Script


On redirecting the user to your given redirect url Google passes an authorization code as a GET parameter named "code". You must use this code and make an API call to get an access token.
After you get the access token you can make another API call to get the user profile information.
<?php
session_start();

// Holds the Google application Client Id, Client Secret and Redirect Url
require_once('settings.php');

// Holds the various APIs involved as a PHP class. Download this class at the end of the tutorial
require_once('google-login-api.php');

// Google passes a parameter 'code' in the Redirect Url
if(isset($_GET['code'])) {
 try {
  $gapi = new GoogleLoginApi();
  
  // Get the access token 
  $data = $gapi->GetAccessToken(CLIENT_ID, CLIENT_REDIRECT_URL, CLIENT_SECRET, $_GET['code']);

  // Access Tokem
  $access_token = $data['access_token'];
  
  // Get user information
  $user_info = $gapi->GetUserProfileInfo($access_token);

  echo '<pre>';print_r($user_info); echo '</pre>';

  // Now that the user is logged in you may want to start some session variables
  $_SESSION['logged_in'] = 1;

  // You may now want to redirect the user to the home page of your website
  // header('Location: home.php');
 }
 catch(Exception $e) {
  echo $e->getMessage();
  exit();
 }
}

?>
     API call to get the access token using the authorization code :
class GoogleLoginApi
{
 ......

 public function GetAccessToken($client_id, $redirect_uri, $client_secret, $code) { 
  $url = 'https://www.googleapis.com/oauth2/v4/token';   
 
  $curlPost = 'client_id=' . $client_id . '&redirect_uri=' . $redirect_uri . '&client_secret=' . $client_secret . '&code='. $code . '&grant_type=authorization_code';
  $ch = curl_init();  
  curl_setopt($ch, CURLOPT_URL, $url);  
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  
  curl_setopt($ch, CURLOPT_POST, 1);  
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost); 
  $data = json_decode(curl_exec($ch), true);
  $http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);  
  if($http_code != 200) 
   throw new Exception('Error : Failed to receieve access token');
  
  return $data;
 }

 ......
}
API call to get user profile information using the access token :
class GoogleLoginApi
{
 ......

 public function GetUserProfileInfo($access_token) { 
  $url = 'https://www.googleapis.com/plus/v1/people/me';   
 
  $ch = curl_init();  
  curl_setopt($ch, CURLOPT_URL, $url);  
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '. $access_token));
  $data = json_decode(curl_exec($ch), true);
  $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);  
  if($http_code != 200) 
   throw new Exception('Error : Failed to get user information');
  
  return $data;
 }

 ......
}
Download Sample code