30 Days of Zumo.v2 (Azure Mobile Apps): Day 5 – Custom Authentication

Over the past two articles, I’ve explored using a server-flow and a client-flow technique to authenticate users to Azure AD and accessing information with Azure Mobile Apps. However, there are times I don’t want social authentication – I want users to sign up to my service and deal with registration, forgotten passwords, etc. Maybe I want to link to an existing user database, or maybe I want to use something that Azure Mobile Apps doesn’t support – like Weibo (ok – that’s a stretch since I don’t speak Chinese). What then?

Azure Mobile Apps is a pro-dev solution. Pretty much everything is changeable or optional. In this tutorial, I’m going to set up Auth0 as a source. Last time I looked at Auth0, it was being used as a client-flow where the token was swapped for a zumo token. That only works if the identity provider is supported by Azure Mobile Apps. This time, I’m going to integrate custom authentication which isn’t supported by Azure Mobile Apps. To do this, I’m going to get the service to accept the Auth0 identity token rather than swapping the token for a zumo token.

Start by setting up Auth0

I’m going to configure a brand new application in Auth0. Sign into the Auth0 dashboard (you have an account, right?). Click on Apps / APIs, then on the big New App/API and give it a name. Then click over to the Settings tab for the new application.

Screen Shot 2016-03-19 at 7.38.23 PM

Add the mobile URI (which is the auth0 tenant domain followed by /mobile) to the allowed Callback URIs. Next I can set up the authentication – this can literally be anything that Auth0 supports. However, I want custom authentication. I want to be able to allow users to sign up or sign in without having a social media account. In the sidebar, there is a Connections section – click on that, then select the Database option underneath it. Set up the database to allow sign-ups:

Screen Shot 2016-03-19 at 7.42.23 PM

I want to force people to set up a new account, so I removed all the social providers from my application definition in the Connections tab for my application.

Take note of the Auth0 Domain, ClientId and ClientSecret – those will be needed later.

Integrating Auth0 Lock into the Apache Cordova App

I’ve got my Apache Cordova app and I’ve integrated the Auth0 Lock process in plenty of times before – it’s one of my favorite methods to authenticate users. Let’s look at the changes. Most of the changes are in www/js/index.js. First the settings:

    // The ADAL Settings
    //var adal = {
    //    authority: 'https://login.windows.net/common',
    //    resourceUri: 'https://30-days-of-zumo-v2.azurewebsites.net',
    //    redirectUri: 'https://30-days-of-zumo-v2.azurewebsites.net/.auth/login/done',
    //    clientId: 'f35243c4-a4da-4b97-8beb-6a1cf2f76976'
    //};

    var auth0 = {
        clientId: '04pHmxVuhYU1QTDo4lEojLo1sseRLfKG',
        domain: 'shellmonger.auth0.com'
    }

The ADAL code isn’t needed any more, so I’ve just commented it out. The auth0 settings for Client ID and Domain are the only things I need. Don’t specify the client secret. That should never be put in any sort of client code, nor should it ever be checked into a source code repository. It’s, well, secret. Treat it as such.

On to the button logic. I have commented out the entire authenticate() method – it isn’t needed for this functionality. The button handler needs to have the Auth0 lock UI:

        // Set up auth0
        auth0.lock = new Auth0Lock(auth0.clientId, auth0.domain);
        auth0.options = {
            focus: true,
            popup: true,
            rememberLastLogin: true,
            authParams: { scope: 'openid email name' },
        };

        // Wire up the button to initialize the application
        $('#loginButton').on('click', function (event) {
            event.preventDefault();

            auth0.lock.show(auth0.options, function (err, token, profile) {
                console.log(err, token, profile);
            });

            //authenticate(function (data) {
            //    console.log(data);
            //    client.login('aad', { 'access_token': data.accessToken })
            //    .then(initializeApp, function (error) {
            //        console.error(error);
            //        alert('Failed to authenticate to ZUMO!');
            //    });
            //});
        });

As with the ADAL investigation, all I’m doing is logging information at this point – not initializing the application. That comes later.

I will also need to add the Auth0 library to the index.html file. That’s a two step process. Firstly, I need to add the library requirements to the content security policy, and that’s a lot of stuff:

        <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://30-days-of-zumo-v2.azurewebsites.net; connect-src https://shellmonger.auth0.com https://30-days-of-zumo-v2.azurewebsites.net; script-src https://cdn.auth0.com https://shellmonger.auth0.com 'self'; style-src https://cdn.auth0.com 'self' 'unsafe-inline'; font-src https://cdn.auth0.com data: 'self'; img-src http://cdn.auth0.com https://www.gravatar.com data: 'self'; media-src *">

This is a complex Content Security Policy – let’s break it down:

Most of these entries are for the Auth0 plugin. I wish Auth0 would use external CSS files so I don’t have to use unsafe-inline, but it is what it is. You can find a great source of information on the Content-Security-Policy website. About the only thing they don’t document is gap: (which is for phonegap/cordova APIs).

Secondly, I need to load the Auth0 Lock library:

        <script type="text/javascript" src="https://cdn.auth0.com/js/lock-8.2.min.js"></script>

Run this project in the Visual Studio Emulator to see the authentication process in progress. The important thing is the data that is logged on the console though. Note that the lock screen is not hidden afterwards – I’ll get to that next. In the console, I get the following:

day-5-pic-1

the important thing is the token. There are some requirements for using 3rd party tokens with an Azure Mobile App:

  • It must follow the Json Web Token format
  • The user Id must be in the subject (sub) field
  • The audience (aud) and issuer (iss) must be known and configured

Head over to http://jwt.io/ and copy your JWT into the Encoded box. The site will decode the JWT for you. Here is mine:

day-5-pic-2

Note that I have a sub field, and the audience and issuer are my Auth0 client Id and domain respectively. Let’s finish off the code on Apache Cordova first, then go configure the server. Here is my button handler:

        // Wire up the button to initialize the application
        $('#loginButton').on('click', function (event) {
            event.preventDefault();

            auth0.lock.show(auth0.options, function (err, profile, token) {
                auth0.lock.hide();
                if (err) {
                    console.error('Error authenticating with Auth0: ', err);
                    alert(err);
                } else {
                    client.currentUser = {
                        id: profile.user_id,
                        profile: profile,
                        mobileServiceAuthenticationToken: token
                    };
                    initializeApp();
                }
            });

As I noted earlier, auth0-lock doesn’t close when it’s finished, so the first thing I do is hide the pop-up. Then I set the ZUMO client.currentUser – the important field here is the mobileServiceAuthenticationToken – this is sent as the X-ZUMO-AUTH string and verified on the server.

Custom JWT Verification in the Server

Now that I have my client in hand, I can work on my server. This is done in two parts. In the Azure Portal, go into your App Service, then All Settings. Go into the Authentication / Authorization blade and turn on the App Service Authentication / Authorization.¬† You don’t need to have any configured services, but the service needs to be turned on.¬†Then go back to All Settings and go to Application Settings. Scroll down to the App Settings section. You need to add an App Setting called Website_Auth_Signing_Key. It is set to the client secret from Auth0.

Note that when you turn off App Service Authentication / Authorization, that isn’t the same as deconfiguration. You can turn it on later and get exactly the same configuration.

day-5-pic-3

Click on Save before leaving the blade. Now, let’s revisit the server code. I need to specify the audience and issuer in the initialization of the azure-mobile-apps SDK:

// Configuration of the Azure Mobile Apps can be done via an object, the
// environment or an auxiliary file.  For more information, see
// http://azure.github.io/azure-mobile-apps-node/global.html#configuration
var mobileApp = azureMobileApps({
    // Explicitly enable the Azure Mobile Apps home page
    homePage: true,
    // Explicitly enable swagger support. UI support is enabled by
    // installing the swagger-ui npm module.
    swagger: true,
    // Authentication settings for custom auth
    auth: {
        audience: '04pHmxVuhYU1QTDo4lEojLo1sseRLfKG',
        issuer: 'https://shellmonger.auth0.com'
    }
});

The audience and issuer must match exactly (including case) what is in the JWT when decoded.

Verifying that the X-ZUMO-AUTH token is working

Since the Authentication / Authorization service is no longer enforcing the X-ZUMO-AUTH token validity, there won’t be any logging to show a bad token. Instead, I need to add some code to log the decoded user during a request. The best place for that is in tables/TodoItem.js – the table controller for the table I am using. Here is my new table controller:

var azureMobileApps = require('azure-mobile-apps');

// Create a new table definition
var table = azureMobileApps.table();

table.read(function (context) {
    console.log('user = ', context.user);
    return context.execute();
});

module.exports = table;

This is a sneak preview for the next article. All I do is log the user object from the passed-in context. If you’ve followed my articles thus far, you will want to check this code into the master branch and then merge it into the azure branch to deploy it:

git add app.js
git add tables/TodoItem.js
git commit -m "Logging for authentication"
git checkout azure
git merge master
git push

Once you hit the final Enter key, the site will re-deploy. While the service is re-deploying, log onto the Azure Portal and select your App Service, then All Settings, then Diagnostic Logs. You want to turn everything on so you can see what is going on. The blade settings should look like this:

day-5-pic-4

Click on Save, then close the blades for the App Service until you are back at the App Service main blade. Now click on Tools and then Log Stream to see the flow of logs that was just enabled. When the cliet logs in, you should see something similar to this:

day-5-pic-5

This is all the information from the JWT that Auth0 passed in.

One final note

You will note that there is a getIdentity() method on the context.auth – it’s really tempting to use it, but that’s for getting additional information on the Azure App Service Authentication / Authorization users. It won’t work when using custom authentication and it’s likely that your server will return a 500 error if you do use it.

Next Steps

I’ve taken the smallest of peeks into the Node.js table controller today – just enough so I can take a look at the authentication response. I’ll use that next time to turn this application into a multi-user application.

Before next time, I’m going to switch everything back to ADAL authentication with a client auth. That will be the standard authentication scheme going forward. Then, next time I’ll be taking a look at the things we can do with the table controller.

Until then, the code is up on my GitHub Repository.

Integrating Auth0 with Azure Mobile Apps JavaScript client

I included a mechanism to get Auth0 working in my Webpack-based React application during my last article. Today I want to go one step further. I want to show how you can use the information you get back from Auth0 to authenticate to Azure Mobile Apps. Azure Mobile Apps has recently released azure-mobile-apps-client v2.0.0-beta4 for JavaScript and Apache Cordova. One of the neat things about this system is that you can use whatever library you like to authenticate a user as long as you get the original identity provider token. That means that you can, for instance, use a Facebook provided library to integrate with the Facebook app and then submit that token to Azure Mobile Apps to generate an Azure App Service token. This is called “client-directed authentication flow”.

It requires a little bit of setup though. In this article, I’m going to go through the process for generating a Microsoft Account, use Auth0 as the UI for the authentication and then integrate it into the Azure Mobile Apps JavaScript SDK.

Step 1: Set up a Microsoft Account Application

Log on to the Microsoft Developer Account. Click on Create Application, then click on API Settings and fill in the form like this:

auth0-zumo-apps-1

Specifically, the Mobile or Desktop Client toggle should be set to No and the Redirect URLs should match your Auth0 callback, which is based on the Auth0 Domain for your application. Log onto Auth0, click on App / APIs and then click on your application to find this information. Click on Save, then click on App Settings. You need to cut-and-paste the Client ID and Client Secret as you will need those.

Step 2: Update your Auth0 Application

You need to set up the Microsoft Account in your application within Auth0. Log into your Auth0 dashboard, click on Connections, then Social and finally Windows Live.

auth0-zumo-apps-2

Cut and paste your Client ID and Client Secret from Step 1 into the relevant boxes. If you want the users email address, make sure you have the right box checked. Click on Save, then close the box.

Step 3: Set up Authentication on Azure App Service

Log onto the Azure Portal, click on All Resources, then your Azure Mobile Apps application (if you don’t have one yet, follow their tutorial). Click on All Settings, then Authentication / Authorization. Now you are in the right place to be setting up authentication.

  • Turn App Service Authentication on
  • Set the action to take when the request is not authenticated to Allow request
  • Turn the Token Store to on (under Advanced Settings).

Now click on Microsoft Account. Cut and paste the Client ID and Client Secret from Step 1, and select the same boxes as you did in Step 2 – these are the claims you are requesting be provided to you.

auth0-zumo-apps-3

This is a most important step. The Client ID and Client Secret MUST be unique to your application (you can’t “try it” in the Auth0 dashboard, for example) and they must match (don’t use two different client ID/secret combos). This will ensure that the token that is provided by Auth0 can be verified by Azure Mobile Apps.

Step 4: Load the Azure Mobile Apps SDK

When you npm install azure-mobile-apps-client, the actual library is in node_modules/azure-mobile-apps-client/dist/MobileServices.Web.min.js – you need to include this as a script reference in your HTML file. At this point, there is no CDN for this library and you can’t “require” the library into Webpack. Those facilities will come later. When it is loaded, you will be able to see a WindowsAzure.MobileServiceClient object within the global context of the browser.

I created a file to create the client like this:

/* global WindowsAzure */

const client = new WindowsAzure.MobileServiceClient(window.APPLICATION.base);
const table = client.getTable('TodoItem');

// Store the client so we can try things
window.APPLICATION.client = client;

export default {
    client: client,
    table: table
};

Now I can do something like:

import zumo from 'path/to/zumo';

This brings in the client and table reference. APPLICATION.base is set to my Azure Mobile Apps URL (in this case, https://ahall-todo-app.azurewebsites.net/) Note that I store the resulting client in my global APPLICATION object – this aids in debugging later on if I need to check something on a live connection.

Step 5: Convert the Auth0 token into an Azure Mobile Apps token

The Auth0 profile that is returned by the lock.show() callback contains an element called identities. There will only be one identity – your Microsoft Account one. In there is an access_token which is the token provided by the identity provider. You can use this as follows:

export function authenticate(profile, token) {
    return (dispatch) => {
        // Start the refresh process
        dispatch(updateLoading(true));

        const loginSuccess = (data) => {
            // Store the original profile and the mobile service auth token
            dispatch(storeProfile(profile, data.mobileServiceAuthenticationToken));
            // Update the loading task to false
            dispatch(updateLoading(false));
        };
        // On failure, clear the authentication
        const loginFailed = (error) => {
            dispatch(storeProfile(null, null));
            dispatch(setErrorMessage(error.message));
        };

        // Trigger the process to swap the token for a zumo-token
        zumo.client.login('microsoftaccount', { access_token: profile.identities[0].access_token })
            .then(loginSuccess, loginFailed); // eslint-disable-line camelcase
    };
}

Note that I’m passing the access token from the identity provider (NOT the auth0 token) to my Azure Mobile Apps client.login() method. If the call succeeds, I’m using Redux and dispatching an action to update my authentication profile. If an error occurs, I’m dispatching an action to set the error message. In my application, this pops up a dialog stating that an error occurred (and clears the login).

Some Common Errors

It’s best to get down to a network level when you are diagnosing problems in this flow – do this by running the application in Chrome and opening up the Developer Tools, then switching to the Network tab. Click the XHR button to only see AJAX requests. When you see a problem, click on the Response for the request that went wrong. Look at the status:

  • A 401 Unauthorized error indicates that you’ve configured Microsoft Account, but the Client ID or Client Secret doesn’t match what’s in Auth0
  • A 404 Not Found error indicates you did not set up the appropriate Identity Provider in Azure Mobile Apps

If you aren’t moving beyond the Sign In button, check out the APPLICATION.client.currentUser and ensure the user information is being filled in.

Auth0 supports many more Identity Providers than Azure Mobile Apps. You only get Facebook, Twitter, Google and Windows Live / Microsoft Account and Azure Active Directory in Azure App Service, so use one of those.

Wrap Up

Want to see the fully working example? I’ve got that on my GitHub repository. My intent is to provide a React for browser example of the Todo application that Azure Mobile Apps uses for their quickstarts. Now I’ve got authentication going, I’m going to move on to using the JavaScript library to cloud-connect this Todo app.

Integrating Auth0 into a Webpack Project

I’ve got a nice webpack-based React application moving towards “completion” (and I put that in quotes because I think a project is never really completed). One of the things I want to do is to integrate Auth0 – I like the presentation of the sign-in project. This article is not about how to configure Auth0 – they do an excellent job of that. Rather, it is about how to get Auth0 working in a Webpack environment. The example webpack project that they provide is, quite simply, wrong (UPDATE: Auth0 corrected the issues within 2 days of this blog being written. Another thing to love about Auth0 – a responsive team!). Here is how to really do it.

Install required components

Along with webpack, you also need a few uncommon loaders:

npm install --save-dev auth0-lock transform-loader json-loader brfs packageify ejsify

The auth0-lock package is the actual Auth0 UI. The json-loader is for including JSON files in the package. The final three packages (brfs, packageify and ejsify) are the same packages used by the Browserify version of the auth0-lock build. That leaves transform-loader, which allows you to use any browserify plugin within webpack. This basically allows you to use code designed for browserify within webpack.

Wondering where Auth0 went wrong with the sample? They left off brfs, packageify and ejsify from the devDependencies in the package.json file.

Adjust the webpack.config.js to compile Auth0

I work on a PC, not a Mac. As a result, the loaders provided within the sample did not work. The path separator is different between a PC and a Mac. Here are my loaders:

loaders: [
    // Javascript & React JSX Files
    { test: /\.jsx?$/, loader: jsxLoader, exclude: /node_modules/ },

    // Auth0-Lock Build
    { 
        test: /node_modules[\\\/]auth0-lock[\\\/].*\.js$/, 
        loaders: [ 'transform-loader/cacheable?brfs', 'transform-loader/cacheable?packageify' ]
    },
    { 
        test: /node_modules[\\\/]auth0-lock[\\\/].*\.ejs$/, 
        loader: 'transform-loader/cacheable?ejsify' 
    },
    { 
        test: /\.json$/, 
        loader: 'json' 
    }
]

Note that my standard loader excludes the node_modules directory. The auth0-lock build explicitly maps the build.

Use Auth0Lock in your React code

I have the following in a React login controller:

import Auth0Lock from 'auth0-lock';

// and later, within the component

    /**
     * Lifecycle event - called when the component is about to mount -
     *  creates the Auth0 Lock Object
     */
    componentWillMount() {
        if (!this.lock)
            this.lock = new Auth0Lock('rKxvwIoKdij6mwpsSvqi7doafDiGR3LA', 'shellmonger.auth0.com');
    }

    /**
     * Event Handler to handle when the user clicks on Sign In button
     *
     * @param {SyntheticEvent} event the button click
     * @returns {boolean} the result
     */
    onClickedLogin(event) {
        const authOptions = {
            closable: true,
            socialBigButtons: true,
            popup: true,
            rememberLastLogin: true,
            authParams: {
                scope: 'openid email name'
            }
        };

        /**
         * Callback for the authentication pop-up
         * @param {Error} err - the error (or null)
         * @param {Object} profile - the user profile
         * @param {string} token - the JWT token
         */
        const authCallback = (err, profile, token) => {
            this.lock.hide();       // Hide the auth0 lock after the callback

            if (err) {
                console.error('Auth0 Error: ', err);
                this.setState({ error: err });
                return;
            }

            console.info('token = ', token);
            console.info('profile = ', profile);
        };

        this.lock.show(authOptions, authCallback);

        // Click is handled here - nowhere else.
        event.preventDefault();
        return false;
    }

Obviously, this does not actually do anything other than print stuff on the console. You will want to store the token and use that to access any resources you want. I’ve got a full redux store update happening when I get a valid login back.

The Most Popular Articles of the Year

I suspect there may be a bunch of blog posts around the Internet that wrap up the year. Here are the most popular articles on my blog for the year:

React with ES6 and JSX

In fifth place, I did a series of articles on working with ECMAScript 2015 and React/Flux, working on getting a typical application working. I also poked into some stage0 proposals for ECMAScript7. I really enjoy working with React, but I’m torn between Custom Elements (and Polymer specifically) and React. Custom Elements are more standard – React is more popular. I’ll be revisiting this again next year (which is in 24 hours, but I’ll likely take longer than that).

Aurelia – a new framework for ES6

In fourth place, people were interested in how I would do my test tutorial with Aurelia. Aurelia is a really interesting framework and I prefer it over Ember and Angular. The learning curve is relatively small, although I will have to revisit the whole framework discussion as Angular 2 and Ember next-gen are coming out. This tutorial included using authentication with Auth0 and accessing remote resources.

ASP.NET MVC6 and Bootstrap

A one-off article on adding Bootstrap to ASP.NET MVC6 applications came in third place. There are other Bootstrap posts that are also interesting, including one that got made into a video.

Talking of ASP.NET MVC6

With the next revision of ASP.NET imminent, I took several strolls through the alpha and beta releases of that framework. There is a lot to like about it and a lot that is familiar. I’ve mostly switched over to a NodeJS environment now, so I’m not expecting to do much more in this area, but it is a much nicer environment that the old ASP.NET.

And finally, Visual Studio Tooling!

Fueled in large part by a link from the ASP.NET Community Articles page, the #1 page for the year was an article I wrote that described the Web Development extensions I used in Visual Studio. It also generated the most discussion with lots of people telling me about their favorite extensions. I’m using Visual Studio Code more these days – it’s lighter weight. I still love this list though.

Next Year

2015 was definitely the year that frameworks changed – In .NET land we got a look at the next revision of the ASP.NET framework, and in JavaScript land we got Aurelia, React, Flux, Relay, Angular-2, ES2015, Web Components, and several new versions of Node. I hope the framework releases calm down in 2016 so we can start sorting out the good from the bad and ugly. I’m going to take new looks at all this and work on my side projects. I hope you will continue the journey with me.

Azure Mobile Apps, NodeJS and Authentication

In a prior article, I introduced the new Azure Mobile Apps SDK, which is open sourced and available on GitHub. In that article, I produced a simple mobile API for accessing table information. It included a dynamic schema and offline sync capabilities.

That mobile app wasn’t actually that useful. In particular, anyone could write anything to my mobile app and I couldn’t control it. How does one control access to the mobile app?

Let’s start again, starting with a standard NodeJS application. Here is my starting application (and it’s located in bin/server.js):

var express = require('express'),
    morgan = require('morgan'),
    staticFiles = require('serve-static'),
    config = require('./config');

var webApp = express();

if (config.isDebugging()) {
  webApp.use(morgan('combined'));
}

webApp.use(staticFiles(config.webRoot, config.options.staticFiles));

webApp.get('/api/settings', function (req, res) {
  res.json(config.settings);
});

webApp.listen(config.webPort, function () {
  console.log('Listening on port ' + config.webPort);
});

This is my starter app, so nothing is peculiar here. If you’ve used ExpressJS at all, you will find this familiar territory. Now, let’s add an unauthenticated mobile app to it. In this case, I’m going to use the dev branch of azure-mobile-apps-node so that I get the latest code:

npm install --save azure/azure-mobile-apps-node#dev

I generally would recommend that you use the latest released version, but it isn’t released yet. It’s still in preview. As a result, things may change here.

To create the mobile WebAPI, I’m going to create a new javascript file called bin/zumo.js:

var azureMobileApp = require('azure-mobile-apps'),
    config = require('./config');

var zumo = azureMobileApp();

zumo.tables.use(function (req, res, next) {
  if (req.user) {
    req.azureMobile.user = req.user;
  }
  return next();
});

zumo.tables.import('./tables');

module.exports = exports = zumo;

The short version of what this code does is:

  1. Create a mobile SDK instance
  2. Handle the authentication object
  3. Import the tables definitions
  4. Export the whole instance for later

The third item there is easy – I have a directory bin/tables that contains a javascript file for the definition of each table. A basic table looks like this (from bin/tables/foo.js):

var azureMobileApps = require('azure-mobile-apps');

var table = azureMobileApps.table();

module.exports = exports = table;

This will create a REST endpoint for /tables/foo. The table name is taken from the filename of the javascript file.

I need to include the following in the bin/server.js to link in the mobile app:

var express = require('express'),
    morgan = require('morgan'),
    staticFiles = require('serve-static'),
    mobileApp = require('./zumo');
    config = require('./config');

var webApp = express();

if (config.isDebugging()) {
  webApp.use(morgan('combined'));
}

webApp.use(staticFiles(config.webRoot, config.options.staticFiles));

webApp.get('/api/settings', function (req, res) {
  res.json(config.settings);
});

webApp.use(mobileApp);

webApp.listen(config.webPort, function () {
  console.log('Listening on port ' + config.webPort);
});

You will have to provide a suitable config object. I’m using a javascript type module. Just look for config.* and ensure your object contains the definitions you need. You can actually run this code – it does the same as I provided last time. It’s just more modularized.

The second part of the zumo.js is interesting. It’s a piece of ExpressJS middleware attached to the /table endpoint. If some other code has created a req.user, then I assume authentication has been done. So I transfer that authentication to the SDK authentication.

If you were doing a mobile app and following the Azure Mobile Apps methodologies for authentication, then req.azureMobile.user would be configured to use the authentication gateway. Your mobile app would have a social authentication sign-in that used the authentication gateway. The authentication gateway would then return a token that would be decoded by the SDK.

However, I’m not doing a mobile app. I’m doing a web app and happen to want to share the token I produce. I am using a JSON web token (which you can decode on jwt.io) produced by Auth0 to secure my connection.

First off, I have a file (bin/jwt.js) that decodes the JWT I’m feeding in the REST API and produces a req.user object:

var jsonwebtoken = require('jsonwebtoken'),
    config = require('./config');

module.exports = exports = function jwt(req, res, next) {
  if (!req.headers.authorization) {
    return next();
  }

  var authParts = req.headers.authorization.split(' ');
  if (authParts[0].toLowerCase() !== 'bearer') {
    return next();
  }

  try {
    var options = {
      algorithm: 'HS256',
      audience: config.settings.auth.ClientID
    };
    var signature = new Buffer(config.authSecret, 'base64');
    var decoded = jsonwebtoken.verify(authParts[1], signature, options);

    if (!decoded.email) {
      return next();
    }

    decoded.id = decoded.email;
    req.user = decoded;
  } catch (err) {
    console.error('[jwt] error decoding token: ', err);
  }
  return next();
};

note that I set the ID to the email address. That’s my unique key for each user. That means that my JWT must contain a claim for the email address. If it doesn’t, then the req.user is not set.

Now I need to link THAT into my bin/server.js:

var express = require('express'),
    morgan = require('morgan'),
    staticFiles = require('serve-static'),
    jwt = require('./jwt'),
    mobileApp = require('./zumo');
    config = require('./config');

var webApp = express();

if (config.isDebugging()) {
  webApp.use(morgan('combined'));
}

webApp.use(staticFiles(config.webRoot, config.options.staticFiles));

webApp.get('/api/settings', function (req, res) {
  res.json(config.settings);
});

webApp.use(jwt);
webApp.use(mobileApp);

webApp.listen(config.webPort, function () {
  console.log('Listening on port ' + config.webPort);
});

Note that the use of the JWT decoder is BEFORE the use of the mobile app. Also, in zumo.js, the use that transfers the req.user into the SDK version is BEFORE the import of the tables. This ordering is important as middleware is executed in sequence.

Now all I need to do is tell the SDK that my table needs to be authorized. To do this, I set the authorise flag (note the British spelling – I approve of this) in the bin/tables/foo.js:

var azureMobileApps = require('azure-mobile-apps');

var table = azureMobileApps.table();
table.authorise = true;

module.exports = exports = table;

I suspect that the GA version of this library will allow the american spelling of authorise. Anglophiles can rejoice in the mean time.

My application has a mechanism of producing tokens (and I’ve covered this process many times in the past. Just click on the auth0 tag to the right). However, I’m going to be using Postman to check the API. First off, let’s do the unauthenticated version:

10062015-1

I get the appropriate 401 Unauthorized response and I can respond to that in my mobile or web app. To send an authenticated request, I submit an Authorization header with the token:

10062015-2

In this case, I’ve submitted the proper Authorization header and the API has accepted it. I can include logging within the request to see the decoded token (it’s in req.user or req.azureMobile.user). The id of the object is my email address from when I signed in.

Note that when I run the application, the Azure Mobile Apps SDK warns me that authentication is not configured. This is because the Gateway Authentication is not configured – we are bypassing that.

Custom Auth vs. Gateway Auth

So, why use custom auth and why use gateway auth? I like custom authentication like this because I develop “offline” and can provide my own token generator – after all, it’s just a JWT. I’m also using a third party authentication library – my web application uses Auth0 Lock which is a pop-up authentication window. No similar utility is provided by Azure.

If you have control over your mobile app and you want to just use the regular Facebook, Twitter, Google and Microsoft sign-in controls, then use the Azure gateway available in Azure Mobile Apps to get a mobile apps token. There are controls available for iOS, Android, Apache Cordova and Xamarin. You can also do a redirect to use the web.

If you want to use a third party authentication provider like Auth0, then use custom authentication. I tend to use Auth0 during development because of the popup Lock component plus the fact that Auth0 has development keys already registered for the four providers.

In either case, you get protected access to the tables configuration.

Building an ES6/JSX/React/Flux App – Part 3 – Authentication

Over the last two posts, I’ve delved into React and built my own Flux Light Architecture, all the while trying to implement the most basic of tutorials – a two-page application with client-side routing and remote data access. It’s now time to turn my attention to authentication. I’m – as ever – going to use my favorite authentication service, Auth0. Let’s first of all get authentication working, then work on how to use it.

New Actions

I need two new actions – one for logging in and one for logging out – to support authentication. This is defined in actions.js like this:

    static login(token, profile) {
        dispatcher.dispatch('LOGIN', { authToken: token, authProfile: profile });
    }

    static logout() {
        dispatcher.dispatch('LOGOUT');
    }

The Auth0 system returns a JSON Web Token and a profile object when you log in to it. These are passed along for storage into the store.

Store Adjustments

I’ve created a pair of new actions that carry data, so I need somewhere to store them. That’s done in the stores/AppStore.js file. First off, I need to initialize the data within the constructor:

    constructor() {
        super('AppStore');
        this.logger.debug('Initializing AppStore');

        this.initialize('pages', [
          { name: 'welcome', title: 'Welcome', nav: true, auth: false, default: true },
          { name: 'flickr', title: 'Flickr', nav: true, auth: false },
          { name: 'spells', title: 'Spells', nav: true, auth: true }
        ]);
        this.initialize('route', this.getNavigationRoute(window.location.hash.substr(1)));
        this.initialize('images', []);
        this.initialize('lastFlickrRequest', 0);
        this.initialize('authToken', null);
        this.initialize('authProfile', null);
    }

I also need to process the two actions – this is done in the onAction() method:

            case 'LOGIN':
                if (this.get('authToken') != null) {
                    this.logger.error('Received LOGIN action, but already logged in');
                    return;
                }
                if (data.authToken == null || data.authProfile == null) {
                    this.logger.errro('Received LOGIN action with null in the data');
                    return;
                }
                this.logger.info(`Logging in with token=${data.authToken}`);
                this.set('authToken', data.authToken, true);
                this.set('authProfile', data.authProfile, true);
                this.changeStore();
                break;

            case 'LOGOUT':
                if (this.get('authToken') == null) {
                    this.logger.error('Received LOGOUT action, but not logged in');
                    return;
                }
                this.logger.info(`Logging out`);
                this.set('authToken', null, true);
                this.set('authProfile', null, true);
                this.changeStore();
                break;

Both action processors take care to ensure they are receiving the right data and that the store is in the appropriate state for the action before executing it.

The UI

There were three places I needed work. The first was in the NavBar.jsx file to bring in a NavToolbar.jsx component:

import React from 'react';
import NavBrand from './NavBrand.jsx';
import NavLinks from './NavLinks.jsx';
import NavToolbar from './NavToolbar.jsx';

class NavBar extends React.Component {
    render() {
        return (
            <header>
                <div className="_navbar">
                    <NavBrand/>
                </div>
                <div className="_navbar _navbar_grow">
                    <NavLinks pages={this.props.pages} route={this.props.route}/>
                </div>
                <div className="_navbar">
                    <NavToolbar/>
                </div>
            </header>
        );
    }
}

The second was the Client/views/NavToolbar.jsx component – a new component that provides a toolbar on the right side of the navbar:

import React from 'react';
import Authenticator from './Authenticator.jsx';

class NavToolbar extends React.Component {
    render() {
        return (
          <div className="_navtoolbar">
            <ul>
              <li><Authenticator/></li>
            </ul>
          </div>
      );
    }
}

export default NavToolbar;

Finally, I needed the Client/views/Authenticator.jsx component. This is a Controller-View style component. I’m using the Auth0Lock library, which can be brought in through dependencies in package.json:

  "dependencies": {
    "auth0-lock": "^7.6.2",
    "jquery": "^2.1.4",
    "lodash": "^3.10.0",
    "react": "^0.13.3"
  },

You should also add brfs, ejsify and packageify to the devDependencies, per the Auth0 documentation. Here is the top of the Client/views/Authenticator.jsx file:

import React from 'react';
import Auth0Lock from 'auth0-lock';
import Logger from '../lib/Logger';
import Actions from '../actions';
import appStore from '../stores/AppStore';

class Authenticator extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            token: null
        };
        this.logger = new Logger('Authenticator');
    }

    componentWillMount() {
        this.lock = new Auth0Lock('YOUR-CLIENT-ID', 'YOUR-DOMAIN.auth0.com');
        this.appStoreId = appStore.registerView(() => { this.updateState(); });
        this.updateState();
    }

    componentWillUnmount() {
        appStore.deregisterView(this.appStoreId);
    }

    updateState() {
        this.setState({
            token: appStore.get('authToken')
        });
    }

I don’t like having the client ID and domain embedded in the file, so I’m going to introduce a local WebAPI to solve that. Ensure you swap in your own Auth0 settings here. Other than that minor change, this is the basic Controller-View pattern. Now for the rendering:

    onClick() {
        if (this.state.token != null) {
            Actions.logout();       // Generate the logout action - we will be refreshed
            return;
        }

        this.lock.show((err, profile, token) => {
            this.lock.hide();
            if (err) {
                this.logger.error(`Error in Authentication: `, err);
                return;
            }
            Actions.login(token, profile);
        });
    }

    render() {
        let icon = (this.state.token == null) ? 'fa fa-sign-in' : 'fa fa-sign-out';
        let handler = event => { return this.onClick(event); };

        return (
            <span className="_authenticator" onClick={handler}>
                <i className={icon}></i>
            </span>
        );
    }

The render() method registers a click handler (the onClick() method) and then sets the icon that is displayed based on whether the current state is signed in or signed out. The onClick() method above it handles showing the lock. Once the response is received from the Auth0 system, I initiate an action to log the user in. If the user was logged in, the click initiates the logout action.

There is a methodology (redirect mode in Auth0 lock) that allows you to show the lock, then the page will be refreshed with a new hash containing the token. You can then store the token and restore the original page. That is all sorts of ugly to implement and follow. I like this version for it’s simplicity. I store the state and values of the authentication in the store, use actions to store that data, but don’t refresh the page.

Checking Authentication

I have a page within this app right now that requires authentication called spells. It never gets displayed because the code in NavLinks.jsx has logic to prevent it. Let’s fix that now.

First, NavLinks.jsx needs a new boolean property called authenticated:

NavLinks.propTypes = {
    authenticated: React.PropTypes.bool.isRequired,
    pages: React.PropTypes.arrayOf(
            React.PropTypes.shape({
                auth: React.PropTypes.bool,
                nav: React.PropTypes.bool,
                name: React.PropTypes.string.isRequired,
                title: React.PropTypes.string.isRequired
            })
        ).isRequired,
    route: React.PropTypes.string.isRequired
};

I can also change the logic within the visibleLinks to check the authenticated property:

        let visibleLinks = this.props.pages.filter(page => {
            if (this.props.authenticated === true) {
                return (page.nav === true);
            } else {
                return (page.nav === true && page.auth === false);
            }
        });

Now, I need to ensure that the NavBar and the AppView bubble the authentication state down the tree of components. That means adding the authenticated property to NavBar (I’ll leave that to you – it’s in the repository) and including it in the NavLinks call:

<NavLinks pages={this.props.pages} route={this.props.route} authenticated={this.props.authenticated}/>

That also means, AppView.jsx must provide it to the NavBar. This is a little more extensive. First of all, I’ve updated the state in the constructor to include an authenticated property:

        this.state = {
            pages: [],
            route: 'welcome',
            authenticated: false
        };

That means updateState() must be updated to account for the new state variable:

    updateState() {
        let token = appStore.get('authToken');
        this.setState({
            route: appStore.get('route'),
            pages: appStore.get('pages'),
            authenticated: token != null
        });
    }

Finally, I can push this state down to the NavBar:

        return (
            <div id="pagehost">
                <NavBar pages={this.state.pages} route={this.state.route} authenticated={this.state.authenticated}/>
                <Route/>
            </div>
        );

With this code, the Spells link will only appear when the user is authenticated.

Requesting API Data

So far, I’ve created an application that can re-jig itself based on the authentication state. But it’s all stored on the client. The authentication state is only useful if you request data from a remote server. I happen to have a Web API called /api/spells that must be used with a valid Auth0 token. You can read about it in a prior post. I’m not going to cover it here. Suffice to say, I can’t get data from that API without submitting a proper Auth0 JWT token. The code in the repository uses User Secrets to store the actual secret for the Auth0 JWT that is required to decode. If you are using the RTM version of Visual Studio 2015, right click on the project and select Manage User Secrets. Your user secrets should look something like this:

{
  "JWT": {
    "Domain": "YOUR-DOMAIN.auth0.com",
    "ClientID": "YOUR-CLIENT-ID",
    "ClientSecret": "YOUR-CLIENT-SECRET"
  }
}

If you run the application and browse to /api/settings, you should see the Domain and ClientID. If you browse to /api/spells, you should get a 401 response.

I can now use the same technique I used when requesting the Flickr data. Firstly, create two actions – one for the request and one for the response (in actions.js):

    static requestSpellsData() {
        dispatcher.dispatch('REQUEST-AUTHENTICATED-API', {
            api: '/api/spells',
            callback: Actions.processSpellsData
        });
    }

    static processSpellsData(data) {
        dispatcher.dispatch('PROCESS-SPELLS-DATA', data);
    }

Then, alter the Store to handle the request and response. This is a place where the request may be handled in one store and the response could be handled in a different store. I have a generic action that says “call an API with authentication”. It then sends the data to whatever action I tell it to. If I had a “SpellsStore”, the spells store could process the spells data on the return. It’s this disjoint method of handling the API call and response that allows me to have stores that don’t depend on one another. I’ve added the following to the constructor of the stores/AppStore.js:

this.initialize('spells', []);

I’ve also added the following to the case statement in onAction():

            case 'REQUEST-AUTHENTICATED-API':
                if (this.get('authToken') == null) {
                    this.logger.error('Received REQUEST-AUTHENTICATED-API without authentication');
                    return;
                }
                let token = this.get('authToken');
                $.ajax({
                    url: data.api,
                    dataType: 'json',
                    headers: { 'Authorization': `Bearer ${token}` }
                }).done(response => {
                    data.callback(response);
                });

            case 'PROCESS-SPELLS-DATA':
                this.logger.info('Received Spells Data: ', data);
                this.set('spells', data);

Finally, I can adjust the views/Spells.jsx file to be converted to a Controller-View and request the data. I’ve already done this for the views/Flickr.jsx. You can check out my work on the GitHub repository.

I’ve done something similar with the Settings API. The request doesn’t require authentication, so I just process it. I also cache the results (if the settings have been received, I don’t need to ask them again). This data is stored as ‘authSettings’ in the store. I then added the authSettings to the state in the views/Authenticator.jsx component. I also need to trigger the settings grab – I do this in the views/Authenticator.jsx component via the componentWillMount() method:

    componentWillMount() {
        if (this.lock == null && this.state.settings != null) {
            this.lock = new Auth0Lock(this.state.settings.ClientID, this.state.settings.Domain);
        } else {
            Actions.requestSettingsData();
        }
        this.appStoreId = appStore.registerView(() => { this.updateState(); });
        this.updateState();
    }

I don’t want the authenticator to be clickable until the settings have been rendered, so I added the following to the top of the render() method:

    render() {
        // Additional code for the spinner while the settings are loaded
        if (this.state.settings == null) {
            return (
                <span className="_authenticator">
                    <i className="fa fa-spinner fa-pulse"></i>
                </span>
            );
        }

This puts a spinner in the place of the login/logout icon until the settings are received.

Wrap-up

One of the biggest differences between MVC and Flux is the data flow. In the MVC architecture, you have a Datastore object that issues the requests to the backend and somehow updates the model, that then informs the controller via a callback (since it’s async). It feels hacky. MVC really works well when the controller can just do the request to get the model from the data store and get the response back to feed the view. Flux feels right in the async front-end development world – much more so than the MVC model.

The Flux architecture provides for a better flow of data and allows the easy integration of caching algorithms that are right for the environment. If you want to cache across restarts of the application (aka page refreshes), then you can store the data into localStore. If you want to specify a server-side refresh (for example, for alerting), then you can integrate SignalR into the system and let SignalR generate the action.

As you can guess, I’m loving the Flux architecture. After getting my head around the flow of data, it became very easy to understand. Code you understand is much easier to debug.

As always, you can get my code on my GitHub Repository.

A Simple App with the AngularJS Framework (Part 2)

In my last post I introduced some major concepts in AngularJS development. I handled models, views and controllers and set up routing. There were a couple of things I did not do, however. The first is the menu bar and the second is authentication. Let’s cover the menu bar first.

The Menu Bar

There are lots of ways to configure a menu bar and I don’t think any one is any better than the others. I could create a custom Angular Directive that takes a DIV and turns it into my nav bar based on a template and a controller. This would be good if I were going to re-use the menu bar time and again.

Alternatively, maybe this is so common that someone else has already done it. There is a great web site – ngmodules.org – that contains a collection of Angular modules that are ready to use. This wouldn’t assist me in learning Angular.

Instead, I’m going to add my code to the main public/index.html file and create another controller. The view will be embedded in the main public/index.html file. Here is the code for the main page:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Angular Test Site</title>
		<link rel="stylesheet" href="jspm_packages/npm/font-awesome@4.3.0/css/font-awesome.min.css">
		<link rel="stylesheet" href="jspm_packages/github/twbs/bootstrap@3.3.5/css/bootstrap.min.css">
		<link rel="stylesheet" href="styles/site.css">
	</head>
	<body ng-app="testApp">
		<header ng-controller="NavBarController">
			<div id="brand">
				<div class="valign-o">
					<div class="valign-i">
						<i class="fa fa-home"></i>
						<span>{{title}}</span>
					</div>
				</div>
			</div>
			<div id="navigation">
				<ul>
					<li ng-class="{ active: isActive('/welcome')}">
						<a href="#/welcome">Welcome</a>
					</li>
					<li ng-class="{ active: isActive('/flickr')}">
						<a href="#/flickr">Flickr</a>
					</li>
				</ul>
			</div>
			<div id="toolbar">
				<ul>
					<li id="navProfile"></li>
					<li id="navSignIn">
						<i class="fa fa-sign-in"></i>
					</li>
				</ul>
			</div>
		</header>

		<div class="page-host">
			<section ng-view></section>
		</div>

		<script src="jspm_packages/github/components/jquery@2.1.4/jquery.min.js"></script>
		<script src="jspm_packages/github/twbs/bootstrap@3.3.5/js/bootstrap.min.js"></script>
		<script src="jspm_packages/github/angular/bower-angular@1.4.2/angular.min.js"></script>
		<script src="jspm_packages/github/angular/bower-angular-route@1.4.2/angular-route.min.js"></script>
		<script src="app.js"></script>
	</body>
</html>

I pretty much copied the additional markup from my Aurelia example. There are some minor tweaks to account for the difference in syntax for including specific code. In this case, I am using the isActive() method within the controller to determine whether to add the active class or not. I’ve included the sign-in toolbar and will get to that in the next section – it’s not necessary for the navigation to work. I use a named controller with the ng-controller directive to wire up my controller to this view.

If I compare this to Aurelia, then I did the same thing in the app.html file – that file became the template for my overall page. In Angular, the root document is the template for my overall page.

I already know how to create a controller, so let’s take a look (thanks to myl on Stack Overflow for this code). I added this to the app.js file:

testApp.controller("NavBarController", [ "$scope", "$location",
	function NavBarController ($scope, $location) {
		$scope.title = "Angular";
		
		$scope.isActive = function (viewLocation) {
			return viewLocation === $location.path();
		};
	}
]);

This does what is expected. I would love, however, to have the nav-bar separated. To do that, I need to write a custom Angular Directive. Here is the code within app.js:

testApp.directive("ngNavbar", function () {
	return {
		restrict: "A",
		templateUrl: "partials/navbar.html"
	}
});

This defines an Attribute (restrict: "A") that I can place on another HTML element. When I put the ng-navbar attribute on that element, its innerHTML will be populated with the template I have specified. I need to create that navbar.html file:

<header>
	<div id="brand">
		<div class="valign-o">
			<div class="valign-i">
				<i class="fa fa-home"></i>
				<span>{{title}}</span>
			</div>
		</div>
	</div>
	<div id="navigation">
		<ul>
			<li ng-class="{ active: isActive('/welcome')}">
				<a href="#/welcome">Welcome</a>
			</li>
			<li ng-class="{ active: isActive('/flickr')}">
				<a href="#/flickr">Flickr</a>
			</li>
		</ul>
	</div>
	<div id="toolbar">
		<ul>
			<li id="navProfile"></li>
			<li id="navSignIn">
				<i class="fa fa-sign-in"></i>
			</li>
		</ul>
	</div>
</header>

This is exactly the same code as was wrapped inside the public/index.html file. Now I can remove that code from the public/index.html file:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Angular Test Site</title>
		<link rel="stylesheet" href="jspm_packages/npm/font-awesome@4.3.0/css/font-awesome.min.css">
		<link rel="stylesheet" href="jspm_packages/github/twbs/bootstrap@3.3.5/css/bootstrap.min.css">
		<link rel="stylesheet" href="styles/site.css">
	</head>
	<body ng-app="testApp">
		<div ng-controller="NavBarController" ng-navbar></div>

		<div class="page-host">
			<section ng-view></section>
		</div>

		<script src="jspm_packages/github/components/jquery@2.1.4/jquery.min.js"></script>
		<script src="jspm_packages/github/twbs/bootstrap@3.3.5/js/bootstrap.min.js"></script>
		<script src="jspm_packages/github/angular/bower-angular@1.4.2/angular.min.js"></script>
		<script src="jspm_packages/github/angular/bower-angular-route@1.4.2/angular-route.min.js"></script>
		<script src="app.js"></script>
	</body>
</html>

This makes the code much more readable. I could also place the controller in the angular directive I’ve just created as well – a task for another time.

Authentication

As I am doing for the other projects, I’m going to use Auth0 for authentication here. Auth0 has provided an excellent tutorial for this purpose, so I am only going to note the differences.

Installing the libraries was mostly done with jspm:

jspm install angular-cookies
jspm install github:auth0/angular-storage
jspm install github:auth0/angular-jwt

The public/index.html file became the following:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<title>Angular Test Site</title>
		<link rel="stylesheet" href="jspm_packages/npm/font-awesome@4.3.0/css/font-awesome.min.css">
		<link rel="stylesheet" href="jspm_packages/github/twbs/bootstrap@3.3.5/css/bootstrap.min.css">
		<link rel="stylesheet" href="styles/site.css">
	</head>
	<body ng-app="testApp">
		<div ng-controller="NavBarController" ng-navbar></div>

		<div class="page-host">
			<section ng-view></section>
		</div>

		<script src="jspm_packages/github/components/jquery@2.1.4/jquery.min.js"></script>
		<script src="jspm_packages/github/twbs/bootstrap@3.3.5/js/bootstrap.min.js"></script>
		<script src="jspm_packages/github/angular/bower-angular@1.4.2/angular.min.js"></script>
		<script src="jspm_packages/github/angular/bower-angular-route@1.4.2/angular-route.min.js"></script>
		<script src="jspm_packages/github/angular/bower-angular-cookies@1.4.2/angular-cookies.min.js"></script>
		<script src="jspm_packages/github/auth0/angular-storage@0.0.11/dist/angular-storage.min.js"></script>
		<script src="jspm_packages/github/auth0/angular-jwt@0.0.9/dist/angular-jwt.min.js"></script>
		<script src="http://cdn.auth0.com/js/lock-7.5.min.js"></script>
		<script src="http://cdn.auth0.com/w2auth0-angular-4.js"></script>
		
		<script src="app.js"></script>
	</body>
</html>

That’s lots of scripts at this point – I’d probably handle this with Browserify or some other sort of bundling technology in a production app. This is good for right now. Note that I’m downloading a couple of the libraries from the Auth0 CDN – I’d probably look into bringing these in as local libraries as well. Auth0 publishes lock on their GitHub page.

The partials/navbar.html page also needed a change – I’ve highlighted the changed lines:

<header>
	<div id="brand">
		<div class="valign-o">
			<div class="valign-i">
				<i class="fa fa-home"></i>
				<span>{{title}}</span>
			</div>
		</div>
	</div>
	<div id="navigation">
		<ul>
			<li ng-class="{ active: isActive('/welcome')}">
				<a href="#/welcome">Welcome</a>
			</li>
			<li ng-class="{ active: isActive('/flickr')}">
				<a href="#/flickr">Flickr</a>
			</li>
		</ul>
	</div>
	<div id="toolbar">
		<ul>
			<li id="navProfile">{{nickname}}</li>
			<li id="navSignIn" ng-click="login()">
				<i class="fa fa-{{icon}}"></i>
			</li>
		</ul>
	</div>
</header>

Lines 22 and 24 bind specific variables in the $scope of the NavbarController to these areas. Line 23 uses the ng-click event handler to call the login method in the NavbarController.

Moving on to the app.js, there are two things I must do. Firstly, I have to configure the module and Angular application for authentication. This is straight from the Auth0 Quick Start Guide:

var testApp = angular.module("testApp", [ 'ngRoute', 'auth0', 'angular-storage', 'angular-jwt' ]);

testApp.config(["$routeProvider", "authProvider", function($routeProvider, authProvider) {
	// Route Map
	$routeProvider
		.when("/welcome", {
			title: "Welcome",
			templateUrl: "partials/welcome.html",
			controller: "WelcomeController"
		})
		.when("/flickr", {
			title: "Flickr",
			templateUrl: "partials/flickr.html",
			controller: "FlickrController"
		})
		.otherwise({
			redirectTo: "/welcome"
		});

	authProvider.init({
		domain: "DOMAIN.auth0.com",
		clientID: "YOUR-CLIENT-ID"
	});
}]);

// This hooks all auth events to check everything as soon as the app starts
testApp.run(function (auth) {
	auth.hookEvents();
});

Line 3 brings in all those libraries that Auth0 said I needed. Line 5 adds the authProvider via dependency injection. The authProvider is provided by Auth0. Line 22-25 actually configures the Auth0 settings. Remember to inject your own domain and clientID here. Finally, line 29-31 ensures all the authentication events are captured as the application starts.

The other area of concern is the NavbarController. Here is the new one:

testApp.controller("NavBarController", [ "$scope", "$http", "auth", "store", "$location",
	function NavBarController ($scope, $http, auth, store, $location) {
		$scope.title = "Angular";
		$scope.nickname = "";
		$scope.icon = "sign-in";

		$scope.isActive = function (viewLocation) {
			return viewLocation === $location.path();
		};

		var profile = store.get("profile");
		if (profile) {
			$scope.nickname = profile.name || profile.nickname;
			$scope.icon = "sign-out";
		};

		$scope.login = function() {
			if ($scope.icon === "sign-out") {
				$scope.nickname = "";
				$scope.icon = "sign-in";
				auth.signout();
				store.remove("profile");
				store.remove("token");
			} else {
				auth.signin({}, function (profile, token) {
					// Success callback
					store.set("profile", profile);
					$scope.nickname = profile.name || profile.nickname;
					store.set("token", token);
					$scope.icon = "sign-out";
					$location.path("/");
				}, function () {
					// Error callback
					alert("Auth0 Error!!!!");
				});
			}
		}
	}
]);

There are two new scope variables. The $scope.nickname will be blank when the user is not logged in and will be filled with something when the user is logged in. The $scope.icon will either be “sign-in” or “sign-out” – this changes the icon that is displayed.

From line 82-86, I set up the initial values of the nickname and icon based on the localStorage (represented by the store variable). The default case is the user is unauthenticated. As a result, I only need to change things if the user is authenticated – i.e. when something is in the profile.

The $scope.login() method is called when the user clicks on the authenticator icon. If the user is signed in, then the user is logged out. If the user is not signed in, then I pop up the Auth0 sign-in window and wait for soemthing to come back. A successful return means that the user is logged in, so I store the token and profile and update the nav bar view.

An Authenticated Page

In my Aurelia review, I added an authenticated page. This page only appeared in the navigation when I was authenticated. It also grabbed data from the backend and displayed it. I wanted the same thing here. First of all, I need an authenticated Web API – changes to server.js:

var express = require("express"),
	jwt = require("express-jwt"),
	morgan = require("morgan"),
	staticFiles = require("serve-static"),
	spells = require("./spells.json"),
	config = require("./config.json");

var app = express();

// Check that the JWT is signed by us
var jwtCheck = jwt({
  secret: new Buffer(config.clientSecret, 'base64'),
  audience: config.clientID
});

// Set the port to listen on
app.set("port", process.env.PORT || 3000);

// Set up logging
app.use(morgan("combined"));

// Set up static files within public
app.use(staticFiles("public"));

// Set up a JWT Check for the /api/spells layer
app.use("/api/spells", jwtCheck);

// Set up the spells endpoint
app.get("/api/spells", function (request, response) {
	response.send(spells);
});


// Listen on the TCP port
app.listen(app.get("port"), function () {
	console.log("Listening on port " + app.get("port"));
});

The spells.json file will be returned when I send an authenticated request to the backend for URI /api/spells. An authenticated request is a request with a valid JSON Web Token in the Authorization header. Your config.json should look like this:

{
	"domain": "YOUR-DOMAIN.auth0.com",
	"clientID": "YOUR-CLIENT-ID",
	"clientSecret": "YOUR-CLIENT-SECRET"
}

Ensure you replace the appropriate values from your configuration in Auth0. Now that I have an authenticated API, I need to display it. Firstly, let’s create a new route for “/spells” to go to the new page:

testApp.config(["$routeProvider", "authProvider",
	 function($routeProvider, authProvider) {
		// Route Map
		$routeProvider
			.when("/welcome", {
				title: "Welcome",
				templateUrl: "partials/welcome.html",
				controller: "WelcomeController"
			})
			.when("/flickr", {
				title: "Flickr",
				templateUrl: "partials/flickr.html",
				controller: "FlickrController"
			})
			.when("/spells", {
				title: "Spells",
				templateUrl: "partials/spells.html",
				controller: "SpellsController"
			})
			.otherwise({
				redirectTo: "/welcome"
			});

		authProvider.init({
			domain: "YOUR-DOMAIN.auth0.com",
			clientID: "YOUR-CLIENT-ID"
		});
	}
]);

Lines 19-23 add the new route to the spells page. I also need a Controller and a View. The Controller is as follows:

testApp.controller("SpellsController", [ "$scope", "$http", "auth", "store",
	function SpellsController ($scope, $http, auth, store) {
		$scope.heading = "Spells";
		$scope.spells = [];
		var url = "/api/spells";
		var headers = {
			"Accept": "application/json"
		};

		// Add the authorization token if we are authenticated
		if (auth.isAuthenticated) {
			headers.Authorization = "Bearer " + store.get("token");
		}

		$http.get(url, {
			"withCredentials": true,
			"responseType": "json",
			"headers": headers
		}).success(function (data, status, headers, config) {
			$scope.spells = data;
		}).error(function () {
			console.error("Error retrieving spells");
		});
	}
]);

The “magic” (such that it is) is in lines 89-91 – if the user is authenticated, I add an Authorization header with the JSON Web Token in it. That is sent with the normal headers. Once the response comes back, I assign the result to the spells variable in the scope. My partials/spells.html view is simple:

<h2>{{heading}}</h2>

<div id="spellList">
	<ul>
		<li ng-repeat="spell in spells">
			{{spell.id}}
		</li>
	</ul>
</div>

The spells variable in the scope is an array. I iterate over that array, pulling out the ID. You should get a bullet list of numbers when this is working.

There are a couple of problems with this version of the code (although it does work). Firstly, the Spells link shows up even when the user is not authenticated. This means that you will see the error message in the console. Secondly, the user gets logged out on page refreshes. This is less than ideal. Fortunately, Auth0 has provided a recipe for the latter issue. Place the following in your app.js file:

// This hooks all auth events to check everything as soon as the app starts
testApp.run([ "$rootScope", "auth", "store", "jwtHelper", "$location",
	function ($rootScope, auth, store, jwtHelper, $location) {
		auth.hookEvents();

		$rootScope.$on("$locationChangeStart", function() {
			var token = store.get("token");
			if (token) {
				if (!jwtHelper.isTokenExpired(token)) {
					if (!auth.isAuthenticated) {
						auth.authenticate(store.get("profile"), token);
					}
				} else {
					$location.path("/");
				}
			}
		});
	}
]);

This code replaces the testApp.run() method. It’s a little different than the version provided by Auth0 – this version takes advantage of the dependency injection in AngularJS v1.4. The version provided by Auth0 is for AngularJS v1.2.

This leaves making the Spells link disappear in the navigation. I already have the auth variable available in the NavBarController so I can create a new isAuthenticated() method and use it the same way as I did the isActive() method:

		$scope.isAuthenticated = function() {
			return auth.isAuthenticated;
		};

Now I can adjust the partials/navbar.html to change the Spells link to be authenticated.

<li ng-class="{ active: isActive('/spells'), 'auth-hide': !isAuthenticated()}">
  <a href="#/spells">Spells</a>
</li>

The auth-hide class is defined in styles/site.css to set display: none.

Note how I check authentication in multiple places. This goes to the “don’t trust the user” principal. I ensure the user can’t see the Spells area. If, however, the user has bookmarked the URI, then I ensure that the authentication is not passed to the backend and hence the data is not shown. If I were being particularly paranoid, I would ensure that a different message was shown and the request was not sent to the backend.

Wrapping Up

That’s it for the Angular test. Over the course of the last two posts, I’ve created controllers, views, routing, authentication and custom directives. This is definitely more complex than Aurelia, but it also has a bigger community, better support (including books, videos, tutorials) and more features. If I were deciding on something other than my own project, I would likely use AngularJS over Aurelia. (This is, of course, before I have investigated Ember, Meteor or React/Flux).

There is a big thing coming though. Angular 2 is the “next version of Angular” and promises to utilize all the features of ECMAScript 6. This warrants it’s own investigation once the code base is a little further along. However, it’s a forklift upgrade, although the Angular team says they will support “Incremental” updates by installing both Angular 1.x and 2.x at the same time. It doesn’t sound ideal.

If you want the code from my small tutorial here, it’s on my GitHub Repository.