Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

JavaScript oAuth

4.97/5 (20 votes)
10 Jul 2014CPOL5 min read 174.9K   3.5K  
Using JavaScript for oAuth with three major identity providers: Facebook, Google, and Twitter.

Introduction

With most modern applications now using HTML and JavaScript, it is very much a wise idea so you keep up with the current trend. Some major entities provide APIs for various reasons which include client authentication and authorization. A popular feature being used for authentication in websites today is "Single Sign-on". This give users the ability to sign into your website using other identity providers especially those from social media websites. This article will demonstrate a simple way of integrating this feature for three major identity providers into your website using purely JavaScript.

Background

In order to utilize the API from the Identity providers, you are required to create an application on their websites which will give you an API key to use in the application.

Using the Code 

If you are not into long reading, you may go ahead and download the source files and use/modify as you please.

Firstly, we include some files in the head of our HTML page.  

HTML
<!--Register Jquery-->
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.1.0.js"></script>
<!--Register Google Api-->
<script src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script>  

In recent times, Twitter has deprecated the use of solely client side authentication which may cause some developers to cringe. However, thanks to YUI (an API provided by Yahoo!) we are able so simulate a server side request to Twitter using JavaScript. So we also include the YUI library in the head.

HTML
<!--Register YUI Api-->
<script type="text/javascript" 
  src="http://yui.yahooapis.com/3.3.0/build/yui/yui-min.js"></script>

We now create three DOM elements to trigger the requests. These elements could be any of your choice.

HTML
<div id="fbLogin" onclick="">Facebook</div>
<div id="twitterlogin">Twitter</div>
<div id="googlelogin">Google</div>   

Now let us look into the script. We'll start with the Facebook log in.


Facebook

The first function we'll create is one to make the initial request to Facebook oAuth API sending the client ID (given in your Facebook app), the redirect URL (must be the same as the one registered in your app), as well as the response type (in this case an access token). The access token is needed to show that the user is authenticated and it will be used to connect to the Facebook graph API and access the user's profile information.

JavaScript
var appID = <YOUR CLIENT ID>;
 
function fbLogin() {
    var path = 'https://www.facebook.com/dialog/oauth?';
    var queryParams = ['client_id=' + appID,
    'redirect_uri=' + window.location,
    'response_type=token'];
    var query = queryParams.join('&');
    var url = path + query;
    window.location.replace(url);
}  

The response will be a redirect to your website with the access token attached as a hash string "#access_token=.......". To use the access token we now need a function to check for the access token in the URL. The function will also make a request to the Facebook graph API sending the access token and a callback function which will receive the user information as a parameter.

JavaScript
function checkFbHashLogin() {
 
    if (window.location.hash.length > 3) {
        var hash = window.location.hash.substring(1);
        if(hash.split('=')[0] == 'access_token')
        {
            var path = "https://graph.facebook.com/me?";
            var queryParams = [hash, 'callback=displayUser'];
            var query = queryParams.join('&');
            var url = path + query;
 
            //use jsonp to call the graph
            var script = document.createElement('script');
            script.src = url;
            document.body.appendChild(script);
        }
       
    }
} 

Now in the third step we'll use the callback function to utilize the user information as we see fit. 

JavaScript
function displayUser(user) {
    setTimeout(function () { }, 1000);
    if (user.id != null && user.id != "undefined") {
       //Do Stuff
       //You have access to user id, name, username, gender etc.
       //For more info visit https://developers.facebook.com/docs/
       //                      reference/login/public-profile-and-friend-list   
    }
    else {
        alert('user error');
    }
}

Lastly, we just need to trigger the function call and also we would have to run the function to check the hash string on page load.

JavaScript
$(function () {
 
    checkFbHashLogin();
 
    $('#fbLogin').click(function () {
        fbLogin();
    });
})

We have now completed the Facebook authentication. 


Google

In this first step, I'll just give the functions while the comments in the code will explain what the functions does. As stated earlier we need to have our client ID and in the case of Google, we have to utilize the API key for the application.

JavaScript
var clientId = <YOUR CLIENT ID>;
var apiKey = <YOUR API KEY>;
var scopes = 'https://www.googleapis.com/auth/plus.me';  
 
 
// Our first function is used to set the api key and
// is run once the google api is loaded in the page header. 
function handleClientLoad() {
    gapi.client.setApiKey(apiKey);
}
 
//Gets the result after the authorization and if successful,
//it makes the api call to get the  //user's information.
function handleAuthResult(authResult) {
 
    if (authResult && !authResult.error) {
        makeApiCall();
    } 
}
  
//Make api call on button click to authorize client
function handleAuthClick(event) { gapi.auth.authorize({ client_id: clientId, 
            scope: scopes, immediate: false }, handleAuthResult);
 
    return false;
}
 
// Load the API and make an API call.  Display the results on the screen.
function makeApiCall() {
    gapi.client.load('plus', 'v1', function () {
        var request = gapi.client.plus.people.get({
            'userId': 'me'
        });
 
        request.execute(function (resp) {
        //Do Stuff
         //You have access to user id, name, display name, gender, emails, etc.
        //For more info visit https://developers.google.com/+/api/latest/people#resource 

        });
    });
}
 
$(function () {
    var authorizeButton = document.getElementById('googlelogin');
    authorizeButton.onclick = handleAuthClick;
})

That completes the Google authentication.


Twitter (Old version of twitter API)

This method will give some errors but it can give a simple overview

As mentioned before, the Twitter API does not allow purely client side authentication. For this reason the YUI library is used. This library makes use of the Yahoo Query Language (YQL) to make server side requests to the Twitter API.

For example, one of the the YQL statements which will be used in the application is

JavaScript
select * from twitter.oauth.requesttoken where oauth_callback="<YOUR WEBSITE URL>";

As you can see the select statement is just like any other query language select statement. The condition parameter for the select statement (oauth_callback) is the callback URL you would have registered with your Twitter app. Because we are selecting where the URLs match, we are not required to use the client ID. Since we are using JavaScript, we can just use window.location to get the current URL for the query (already taken care of in the code). In essence we need not worry about YUI and the YQL queries. Hence, let us now look at the implementation of the YUI library and how it is used to make the Twitter API calls.

The first step is initializing the YUI object. Within this object we are going to set the modules that will be used and their location. In our case we are using the Twitter and YQL modules.

JavaScript
YUI({
    combine: false,
    filter: "raw",
    debug: false,
    modules: {
        
        'Twitter': {
           fullpath: 'js/twitter.js'
        },
        'myYQL': {
            fullpath: 'js/yql.js',
            requires: ['jsonp', 'jsonp-url']
        }
    }
})

In the next step, we'll tell the YIU library which components we want to use from its repository and also provide a callback function. We do this by calling the YUI "use' function which is appended to the YUI object after initialization.

JavaScript
YUI({
    ...
}).use('Twitter', 'gallery-storage-lite', 'myYQL', 'node', "event", function (Y) {}); 

The callback function will be executed right after the YUI library is initialized and components, therefore we'll put all the code to handle the authorization for the Twitter API in this function. The first thing to do is to get the element that will trigger the Twitter authorization and binding its click event with a function. This function will make the first API call to get oAuth request token and secret. These will be passed in a query string to the Twitter authenticate API and the oAuth token verifier returned in like manner.

JavaScript
var twtBtn = Y.one('#twitterlogin');
 
twtBtn.on('click', function (e) {
    Y.Twitter.call({ type: "request_token" }, function (tokens) {
        Y.log("step 1");
        Y.log(tokens);
        Y.StorageLite.setItem('oauth_token', tokens.oauth_token);
        Y.StorageLite.setItem('oauth_token_secret', tokens.oauth_token_secret);
        window.setTimeout(function () {
            window.location = "https://twitter.com/oauth/authenticate?oauth_token=" + 
              tokens.oauth_token + "&oauth_token_secret=" + tokens.oauth_token_secret;
        }, 10);
    });
}); 

The next few steps are combined in nested calls and responses until we get the final response. We first check the query string to get the oAuth token verifier. The token and verifier are then passed to the YUI Twitter call to get the access tokens. Finally the access tokens are sent in a call to retrieve the user's information.

JavaScript
if (getQueryStringParameter('oauth_token')) {
 
    Y.StorageLite.setItem('oauth_token', getQueryStringParameter('oauth_token'));
    Y.StorageLite.setItem('oauth_verifier', getQueryStringParameter('oauth_verifier'));

    Y.Twitter.config({
        oauth_token: getQueryStringParameter('oauth_token'),
        oauth_token_secret: getQueryStringParameter('oauth_token_secret')
    });

    Y.Twitter.call({ type: "access_token" }, function (tokens) {
        Y.Twitter.config({
            oauth_token: tokens.oauth_token,
            oauth_token_secret: tokens.oauth_token_secret
        });

        Y.Twitter.call({ type: "credentials" }, function (user) {
            Y.Twitter.config({
                screen_name: user.screen_name,
                user_id: user.id
            });

            //Do Stuff
        //You have access to user id, name, screenname, description, etc.
        //For more info visit https://dev.twitter.com/docs/api/1.1/get/account/verify_credentials 
       });
    });
}

That would complete all the requests for the Twitter authentication component.


JavaScript
//Supporting function to parse the query string 
function getQueryStringParameter(key, queryString) {
    
    var queryString = queryString || window.location.href;
    key = key.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
    var regex = new RegExp("[\\?&]" + key + "=([^&#]*)");
    var qs = regex.exec(queryString);
    if (qs)
        return qs[1];
    else
        return false;
}

Points of Interest 

The utilization of single sign-on is rapidly growing and many major websites such as Yahoo! and Hotmail allow users identity for single sign-on. For example, when configuring your Google API app you are able to tie other providers with your Google API key. Also note that all requests should initiate from the domain that is registered in each respective Identity provider's application and you will be required to use a valid domain and website URL. For this reason, the application will not work successfully from your localhost. 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)