Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Using Oauth 2.0 In Your Web Browser With AngularJS

TwitterFacebookRedditLinkedInHacker News

I have a few popular Oauth related posts on my blog. I have one pertaining to Oauth 1.0a, and I have one on the topic of Oauth 2.0 for use in mobile application development. However, I get a lot of requests to show how to accomplish an Oauth 2.0 connection in a web browser using only JavaScript and AngularJS.

We’re going to better explore the process flow behind Oauth 2.0 to establish a secure connection with a provider of our choice. In this particular example we’ll be using Imgur because I personally think it is a great service.

Before we begin, it is important to note that this tutorial will only work with providers that offer the implicit grant type.

Oauth Implicit Grant Type via OauthLib:

The implicit grant type is used to obtain access tokens (it does not support the issuance of refresh tokens) and is optimized for public clients known to operate a particular redirection URI. These clients are typically implemented in a browser using a scripting language such as JavaScript.

Unlike the authorization code grant type, in which the client makes separate requests for authorization and for an access token, the client receives the access token as the result of the authorization request.

You’ll know the provider supports the implicit grant type when they make use of response_type=token rather than response_type=code.

So there are going to be a few requirements to accomplish this in AngularJS:

  1. We are going to be using the AngularJS UI-Router library
  2. We are going to have a stand-alone index.html page with multiple templates
  3. We are going to have a stand-alone oauth_callback.html page with no AngularJS involvement

With that said, let’s go ahead and create our project to look like the following:

project root
    templates
        login.html
        secure.html
    js
        app.js
    index.html
    oauth_callback.html

The templates/login.html page is where we will initialize the Oauth flow. After reaching the oauth_callback.html page we will redirect to the templates/secure.html page which requires a successful sign in.

Crack open your index.html file and add the following code:

<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.27/angular.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.13/angular-ui-router.min.js"></script>
        <script src="js/app.js"></script>
    </head>
    <body ng-app="example">
        <div ui-view></div>
    </body>
</html>

Now it is time to add some very basic HTML to our templates/login.html and templates/secure.html pages:

<h1>Login</h1>
<button ng-click="login()">Login with Imgur</button>

The above code goes in the templates/login.html page and the below code goes in the templates/secure.html page:

<h1>Secure Web Page</h1>
<b>Access Token: </b> {{accessToken}}

Not much left to do now. Open your js/app.js file and add the following AngularJS code:

var example = angular.module("example", ['ui.router']);

example.config(function($stateProvider, $urlRouterProvider) {
    $stateProvider
        .state('login', {
            url: '/login',
            templateUrl: 'templates/login.html',
            controller: 'LoginController'
        })
        .state('secure', {
            url: '/secure',
            templateUrl: 'templates/secure.html',
            controller: 'SecureController'
        });
    $urlRouterProvider.otherwise('/login');
});

example.controller("LoginController", function($scope) {

    $scope.login = function() {
        window.location.href = "https://api.imgur.com/oauth2/authorize?client_id=" + "CLIENT_ID_HERE" + "&response_type=token"
    }

});

example.controller("SecureController", function($scope) {

    $scope.accessToken = JSON.parse(window.localStorage.getItem("imgur")).oauth.access_token;

});

We are first going to focus on the login method of the LoginController. Go ahead and add the following, pretty much taken exactly from the Imgur documentation:

$scope.login = function() {
    window.location.href = "https://api.imgur.com/oauth2/authorize?client_id=" + "CLIENT_ID_HERE" + "&response_type=token"
}

This long URL has the following components:

ParameterDescription
client_idThe application id found in your Imgur developer dashboard
response_typeAuthorization grant or implicit grant type. In our case token for implicit grant

The values will typically change per provider, but the parameters will usually remain the same.

Now let’s dive into the callback portion. After the Imgur login flow, it is going to send you to http://localhost/oauth_callback.html because that is what we’ve decided to enter into the Imgur dashboard. Crack open your oauth_callback.html file and add the following source code:

<html>
    <head>
        <script>
            var callbackResponse = (document.URL).split("#")[1];
            var responseParameters = (callbackResponse).split("&");
            var parameterMap = [];
            for(var i = 0; i < responseParameters.length; i++) {
                parameterMap[responseParameters[i].split("=")[0]] = responseParameters[i].split("=")[1];
            }
            if(parameterMap.access_token !== undefined && parameterMap.access_token !== null) {
                var imgur = {
                    oauth: {
                        access_token: parameterMap.access_token,
                        expires_in: parameterMap.expires_in,
                        account_username: parameterMap.account_username
                    }
                };
                window.localStorage.setItem("imgur", JSON.stringify(imgur));
                window.location.href = "http://localhost/index.html#/secure";
            } else {
                alert("Problem authenticating");
            }
        </script>
    </head>
    <body>Redirecting...</body>
</html>

If you’re familiar with the ng-cordova-oauth library that I made, you’ll know much of this code was copied from it. Basically what we’re doing is grabbing the current URL and parsing out all the token parameters that Imgur has provided us. We are then going to construct an object with these parameters and serialize them into local storage. Finally we are going to redirect into the secure area of our application.

In order to test this we need to be running our site from a domain or localhost. We cannot test this via a file:// URL. If you’re on a Mac or Linux machine, the simplest thing to do is run sudo python -m SimpleHTTPServer 80 since both these platforms ship with Python. This will run your web application as localhost on port 80.

A video version of this article can be seen below.

Nic Raboy

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in C#, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Unity. Nic writes about his development experiences related to making web and mobile development easier to understand.