Social Authentication – Node Style

I’m currently in the middle of a Node investigation. Here was the list of my requirements:

  1. I need to be able to run a small web server
  2. I need to be able to handle templated views with server-side code
  3. I need to be able to do social authentication
  4. I need to be able to use an MVC architecture
  5. I need to be able to provide a Web API
  6. I need to be able to publish a node app to Azure
  7. I need to be able to edit node applications in Visual Studio 2015

Today is all about social authentication. Research on google tells me that I should use Passport which is a modular middleware for – you guessed it – authentication in a node/express environment. I recently met with the guys at Auth0 and their technology impressed me. You can do one call to one provider and authenticate to many environments – including enterprise accounts like Active Directory and Azure AD. I just want Twitter right now, but that is simply awesome, so I’m planning on integrating that technology as well.

Step 1: Sign up for a free Auth0 Account

You only start paying for Auth0 usage when you go into production. I’m not going into production, so I am using their free account. Just go onto their home page and click the big button to sign up.

Their process also walks you through creating a default app. This is perfectly fine for what I’m going to do – just make sure you select Twitter authentication when you do this process.

Step 2: Set up the Auth0 Default App

In the Auth0 management screen, select the Apps / APIs option on the left hand menu, then click on the Default App. A screen shot is shown below with obfuscated client credentials.


Note the callback URL. I have to set that to whatever my website is running as. The URL http://localhost:3000 is where my node application lives. If I were running this in Azure, then I would have something like Take note of the domain, client ID and client secret that I have blacked out – these are important later.

Step 3: Write an Auth0 strategy file

While we are logged on to the auth0 management portal, click over to Quick Start and select a Regular Web Site on Node.JS. It has some boiler-plate code there. In Step 2, there is a section of code for configuring Passport for Auth0. Cut and paste that into a file in your project called auth0-strategy.js. Mine (with adjustments for obfuscating secrets) looks like this:

var passport = require('passport');
var Auth0Strategy = require('passport-auth0');

var strategy = new Auth0Strategy({
    domain:       '{{DOMAIN}}',
    clientID:     '{{CLIENTID}}',
    clientSecret: '{{CLIENTSECRET}}',
    callbackURL:  '/callback'
  }, function(accessToken, refreshToken, extraParams, profile, done) {
    // accessToken is the token to call Auth0 API (not needed in the most cases)
    // extraParams.id_token has the JSON Web Token
    // profile has all the information from the user
    return done(null, profile);


// This is not a best practice, but we want to keep things simple for now
passport.serializeUser(function(user, done) {
  done(null, user);

passport.deserializeUser(function(user, done) {
  done(null, user);

module.exports = strategy;

The three pieces I have obfuscated are the three pieces I blacked out when configuring the default app above.

Step 4: Add a Login Page

I cheated for the login page. I have a client/login.html file with the following contents:

<!DOCTYPE html>
  <meta charset="utf-8">
  <h1><a href="https://{{DOMAIN}}{{CLIENTID}}&redirect_uri=http://localhost:3000/callback&connection=twitter">Twitter</a></h1>

The URL is further down the quick start page. In the drop-down for section 6, select “Plain Link” and you will get this URL. Now I just have to click on that link and it will initiate the login sequence.

Step 5: Update the main server file

Finally, I need to update the main server file – index.js – to add in authentication. First of all, I need some new libraries. Install them with npm:

npm install --save passport passport-auth0 cookie-parser express-session

I also need to bring in the libraries at the top of index.js:

var express = require("express"),
    partials = require("express-partials"),
    ejs = require("ejs"),
    passport = require("passport"),
    cookieParser = require("cookie-parser"),
    session = require("express-session"),
    auth0strategy = require("./auth0-strategy");

There are three things I need to do in the main server file:

  1. Configure the Passport system with the Auth0 Strategy
  2. Do a redirect to the login page if the user is unauthenticated
  3. Handle the callback from Auth0

First up is configuration. I’ve added the following code (which is boilerplate from the auth0 quick start):

// Set up express to use the passport authentication middleware
app.use(session({ secret: "my-little-secret" }));

This is placed alongside the other app.use() method calls.

Let’s say a user is unauthenticated. They browse to the home page. The first thing I want to happen is to redirect the user to the login page that I created in Step 4. To do that, I’ve added some code to the home page view handler. In fact, this was why I wanted a view handler in the first place – so I could inject some server side code:

// Serve up pages - Home Page
app.get("/", function(req, res) {
  if (!req.isAuthenticated()) {
  } else {
    res.render("index", {
      title: "Index Page (from index.js)",
      user: req.user

The user will get served up the /client/login.html page which has that single Twitter link on it. They will click on that and be redirected to the Auth0 site. Auth0 will do it’s magic to authenticate the user and redirect back to the redirect_url from the Twitter link in /client/login.html (this redirect URL is also registered on the Auth0 site).

That redirection goes to /callback. I’ve added the following code directly before the home page handler to handle the callback:

// Serve up pages - Callback handler from Auth0
  passport.authenticate("auth0", {
    failureRedirect: "/client/failure.html"
  function(req, res) {
    if (!req.user) {
      throw new Error("user is null");
    console.log("User is %o", req.user);

When the user is redirected back to /callback, it presents a new cookie. The passport.authenticate method calls does a call back to Auth0 to ask if the cookie is valid and if so to fill in the details of the user. If that succeeds, then the user is redirected back to the home page, but this time in an authenticated state.

Note I’ve printed the req.user object. This has all sorts of interesting information in it:

User is %o { provider: 'twitter',
  displayName: 'Adrian Hall',
  id: 'twitter|257173506',
  name: { familyName: undefined, givenName: undefined },
  picture: '',
  nickname: 'Adrian Hall',
   [ { access_token: '**REMOVED**',
       access_token_secret: '**REMOVED**',
       provider: 'twitter',
       user_id: 257173506,
       connection: 'twitter',
       isSocial: true } ],
   { name: 'Adrian Hall',
     picture: '',
     description: 'Big Data in IT operations.',
     lang: 'en',
     location: 'Seattle, WA, US',
     screen_name: 'FizzyInTheHall',
     time_zone: 'Pacific Time (US &amp; Canada)',
     url: '',
     utc_offset: -25200,
     clientID: '{{CLIENTID}}',
     user_id: 'twitter|257173506',
     nickname: 'Adrian Hall',
     identities: [ [Object] ],
     created_at: '2015-04-27T17:19:41.812Z' },
  _raw: '**REMOVED**' }

I could add something like <%= user.displayName %> to my view (since I’ve added the user object to the model) and get the display name.

Final Thoughts on Authentication

There are some competing styles for authentication – OAuth 1, OAuth 2 and OpenID are some of the more visible and commonly used ones in social authentication. Which one is better? That requires an understanding of the politics and technical development that are beyond me – which is why I think a provider like Auth0 (or its arch nemesis – is a good idea. In the end, writing one connector and handling multiple providers makes life easier for you – the developer – with no loss of functionality for your user.

It’s a good idea to get a good grasp on how these work so you can see what is going on via Fiddler when authentication is not working.

As always, my work is published on my GitHub Repository.