When I switched from a Express based web application to a single page application one of the biggest hurdles I faced was how to handle user authentication. Auth0 solved that issue, next was figuring out how the authenticated user would interact with the rest of my application.

Generally I would generate a unique ID for the user and all ancillary data would be associated with that ID. When another party maintains your users though you have to get creative.

App and user metadata

Auth0 provides two stores for metadata. App metadata stores metadata that can impact an applications core functionality such as support plan, how an application functions or what the user can access. These are things you would not want to be editable by the user.

User metadata on the other hand can be used to store other information such as user preferences and any other information that would not impact how an application functions.

Below is an example of a user object:

{
    "emails": "jane.doe@example.com",
    "user_metadata": {
        "hobby": "surfing"
    },
    "app_metadata": {
        "plan": "full"
    }
}

It is possible to read and write this data through Auth0 APIs but today I will focus on setting app metadata when a user is created.

Working with Rules and Hooks

Back to our example application, I need a way to uniquely identify a user. I would like to create a userid field that will contain a UUID inside app_metadata because that is a value the user should never change.

Luckily Auth0 exposes rules and hooks that allow you to run functions when a user logs in to your application or is created. Hooks are triggered when a user logs in with an email/password login, while rules will work with both social logins (logging in with Facebook, Google, etc.) as well as email/password logins.

If you are familiar with NodeJS you will find writing rules and hooks will come naturally. Adding a rule is easy, go to your Auth0 dashboard and click on the rules link then click on "Create Rule".

As an example, here is a function that will generate a UUID and assign the value to the userid in app metadata.

function (user, context, callback) {
  var uuid = require('uuid');
  var generated = uuid();
  
  user.app_metadata = user.app_metadata || {};
  user.app_metadata.userid = user.app_metadata.userid || generated;
  
  auth0.users.updateAppMetadata(user.user_id, user.app_metadata)
   .then(function(){
       callback(null, user, context);
    })
    .catch(function(err){
        callback(err);
    });   
}

Hooks, which are in beta, give you a few options of interception points: client credential exchange, post user registration and pre user registration. Hooks are created like rules, click the Hooks link on the Dashboard, click "Create Hook" and then select the interception point. Here is the hook that corresponds to the rule above using the post user registration interception point.

/**
@param {object} user - The user being created
@param {string} user.tenant - Auth0 tenant name
@param {string} user.username - user name
@param {string} user.password - user's password
@param {string} user.email - email
@param {boolean} user.emailVerified - is e-mail verified?
@param {string} user.phoneNumber - phone number
@param {boolean} user.phoneNumberVerified - is phone number verified?
@param {object} context - Auth0 connection and other context info
@param {string} context.requestLanguage - language of the client agent
@param {object} context.connection - information about the Auth0 connection
@param {object} context.connection.id - connection id
@param {object} context.connection.name - connection name
@param {object} context.connection.tenant - connection tenant
@param {object} context.webtask - webtask context
@param {function} cb - function (error, response)
*/
module.exports = function (user, context, cb) {
  var response = {};
  var uuid = require('uuid');
  var id = uuid();
  
  response.user = user;
  
  // Add user or app metadata to the newly created user
  response.user = {
    app_metadata: { userid: id }
  };
  cb(null, response);
    
};

The hook editor is modeled after the new web task editor. As you can see you have access to quite a bit of user and context data.

Wrapping it all up

This is just a simple example, but you can easily accomplish more complicated tasks or normalize your user information. Reading the documentation it would seem the modules available to rules is not quite as robust as what is available to hooks but that did not really limit what I could accomplish. Mostly I have leveraged the request module which is available to both rules and hooks to relay information back to the server if user creation is successful.

I have not spent much time trying to communicate with Auth0 through their API, perhaps that is another post for another day.

Updated 7/23/18: Rules apply to social and db logins, Hooks are db only currently