Before using popular API services like Google*, Facebook* or Instagram* in HTML5 apps, you have to first authenticate with the service. Most services today use Oauth 2.0 to authenticate the users with applications.
The OAuth 2.0 authorization framework enables a user to authorize a third-party application to access a HTTP service, Oauth2 service grants a access_token to the application which is used to access the APIs. Most Oauth2 services support 2 methods of obtaining authorization:
- Authorization code grant flow
- Implicit grant flow
Oauth2 Authorization code grant flow on the web opens the service authorization page so that user to login and authorize the application, after successful authorization the service redirects back to the application with a "code" in URL parameter. The application uses this "code" along with "client_secret" to request a "access_token".
Oauth2 implicit grant flow on the web opens the service authorization page for user to login and authorize the application, after successful authorization the service redirects back to the application with a "access_token" in URL hash fragment.
Implementing this Oauth2 flow on website is straight forward since the website can redirect to display login page and then return back. However this becomes tricky to do this in a hybrid HTML5 app. One way to implement Oauth2 flow in HTML5 packaged apps is by using Cordova's InAppBrowser.
Here are the steps involved in doing a Oauth2 Authorization Code grant flow in a Cordova* HTML5 app:
- Open Oauth2 authorization page in Cordova InAppBrowser
- Get the authorization code from the redirected URL using the loadstart event listener
- Request access_token using the authorization code
Here are the steps involved in doing a Oauth2 Implicit Grant flow in a Cordova* HTML5 app:
- Open Oauth2 authorization page in Cordova InAppBrowser
- Get the access_token from the redirected URL hash fragment using the loadstart event listener
Below is detailed explanation of each steps with relevant code snippets. The code for doing Oauth2 in Cordova app and example is available on github.
Open Oauth2 authorization page in Cordova InAppBrowser
The URL for Oauth2 authorization page can be found in the Service documentation, such as Oauth2 documentation for Google* Oauth2 and Facebook* Oauth2. These have details about the auth_url and token_url required for authorization and token request. You first have to register a application client with the Oauth2 service provider to get the client_id, client_secret and setup a redirect_uri. The redirect URI can be any web address or even just a localhost URL, this redirect_uri is used by the Oauth2 service to send the authorization code back to the application which should be used to request access_token. Below is an example of Google* Oauth2 configuration page:
Once you have the client_id, client_secret and redirect_uri, you can create the login URL and open it in a Cordova InAppBrowser like this:
var login_url = auth_url + '?' + $.param({ client_id: client_id, redirect_uri: redirect_uri, response_type: response_type }); var loginWindow = window.open(login_url, '_blank', 'location=yes');
Setting the response_type to "code" will do Authorization code grant flow and setting it to "token" will do an implicit grant flow. The above code will open the login page in Cordova InAppBrowser like shown below:
Get the access_token from the redirected URL hash fragment
Once the user logs in and authorizes the application, the login page will be redirected to the redirect_uri with hash fragment in the URL (implicit grant), this will contain either an access_token or error in a query string format. Below is the code to get access_token from the hash fragment:
$(loginWindow).on('loadstart', function(e) { var url = e.originalEvent.url; var access_token = url.split("access_token=")[1]; ... }
Get the authorization code from the redirected URL
Once the user logs in and authorizes the application, the login page will be redirected to the redirect_uri with a code parameter in the URL (authorization code grant). To get this code, a "loadstart" event listener is attached to the InAppBrowser and the url is checked for either "code=" or "error=" in the URL parameter. Below is the code for InAppBrowser event listener:
$(loginWindow).on('loadstart', function(e) { var url = e.originalEvent.url; ... }
Request access_token using the authorization code
Once we receive the "code" or "error" in redirect_uri, we do not need the InAppBrowser anymore, so we first close it using the .close() method:
if (code || error){ loginWindow.close(); ... }
The "code" received in the redirect_uri is required to get back the access_token from the Oauth2 service provider, this is accomplished by doing an AJAX POST call to the Token request URL (token_url) with code, client_id, client_secret and redirect_uri. The token_url for the service will be available in documentation. Below is the code snippet for doing the AJAX POST call, the response will be either a JSON object or a simple query string with access_token which can be parsed and then used to make other API calls.
if (code) { $.ajax({ url: token_url, data: {code:code, client_id: client_id, client_secret: client_secret, redirect_uri: redirect_uri, grant_type:"authorization_code"}, type: 'POST', success: function(data){ // get access_token }, error: function(error){ // show error } }); } else if (error) { // show error }
The full source code is available as a jQuery* plugin on github There is also an example app code which can be configured to login to any Oauth2 service. This cordova-oauth2 jQuery* plugin supports both authorization code grant flow and implicit grant flow. Implicit grant flow is recommended since it does not require the app code to store the client_secret.
You can use Intel XDK to test the Cordova Oauth2 example, you can test in the Intel XDK emulator, test on device or build the app and install on device. This example works when built using either Intel XDK, Phonegap* build or Cordova CLI.