Login with Auth0

A very common use case with <form.io> is to integrate it with the amazing authentication platform called Auth0. This integration can be used to bring the following functionality into your <form.io> application.

  • Passwordless logins
  • OAuth implementations
  • Reset Password
  • Breached password capability

The following talks about how you can implement this service within a <form.io> application.

Adding Rules to Auth0

After you create your Auth0 account, you will first want to create a new Rule within your account.

  • Click on the section called Rules
  • Click on the button that says Create Rule
  • Select Empty Rule
  • Give your rule a title such as Formio Integration
  • Within the contents, copy and paste the following.
function (user, context, callback) {

  // Your Form.io Project API
  var FORMIO_PROJECT_API = 'https://yourproject.form.io';

  // Secret password used for all Form.io accounts (KEEP THIS SECRET!)
  var FORMIO_DEFAULT_PASS = 'user-default-password-secret';

  // skip if no email
  if(!user.email) return callback(null, user, context);

  /**
   * Check to see if a user exists.
   *
   * @param email
   * @param next
   */
  var userExists = function(email, next) {
    request({
      uri: FORMIO_PROJECT_API + '/user/exists',
      method: 'GET',
      qs: {
        'data.email': email
      }
    }, function(error, response) {
      var status = parseInt(response.statusCode, 10);
      if (status === 200) {
        return next(null, true);
      }
      else if (status === 404) {
        return next(null, false);
      }
      return next(error);
    });
  };

  /**
   * Register a new user provided the default password and user info.
   *
   * @param userInfo
   * @param next
   */
  var registerUser = function(userInfo, next) {
    userInfo.password = FORMIO_DEFAULT_PASS;
    request({
      uri: FORMIO_PROJECT_API + '/user/register',
      method: 'POST',
      json: {
        data: userInfo
      }
    }, function(error, response) {
      if (error) {
        return next(error);
      }
      next(null, response.headers['x-jwt-token']);
    });
  };

  /**
   * Log in the user using the email and default password.
   *
   * @param email
   * @param next
   */
  var loginUser = function(email, next) {
    request({
      uri: FORMIO_PROJECT_API + '/user/login',
      method: 'POST',
      json: {
        data: {
          email: email,
          password: FORMIO_DEFAULT_PASS
        }
      }
    }, function(error, response, data) {
      if (error) {
        return next(error);
      }
      next(null, response.headers['x-jwt-token']);
    });
  };

  /**
   * Retrieve a user token. This accomplishes this task using a few steps.
   *   1.) Check to see if the user exists within Form.io
   *   2.) If yes, then we will simply log the user in with the default password.
   *   3.) If no, then we will register them into the system which also logs them in.
   *
   * @param userInfo - The user information passed to us from Auth0.
   * @param next
   */
  var getUserToken = function(userInfo, next) {
    userExists(userInfo.email, function(err, exists) {
      if (err) {
        return next(err);
      }
      if (exists) {
        loginUser(userInfo.email, next);
      }
      else {
        registerUser(userInfo, next);
      }
    });
  };

  // Get the user token.
  getUserToken(user, function(err, jwtToken) {
    // Let the user know if an error occured.
    if (err) {
      return callback(err);
    }

    // Add the Form.io JWT token to the user metadata and return.
    user.user_metadata = user.user_metadata || {};
    user.user_metadata.formio = {token: jwtToken};
    auth0.users.updateUserMetadata(user.user_id, user.user_metadata);
    return callback(null, user, context);
  });
}

Auth0 + Form.io integration

Now that you have a rule setup, the next step is to create an application and integrate Form.io within that application. For this example, we will start with an application provided by Auth0 found @ https://auth0.com/docs/quickstart/spa/angularjs/01-login.

Once you download this application, you will need to install all dependencies by typing.

bower install

You will then need to install the formio.js library by typing the following.

npm install formiojs

And then provide the following within the /index.html file.

<script type="text/javascript" src="node_modules/formiojs/dist/formio.min.js"></script>

Once you do that, you can then put the following within the /auth0-variables.js file.

var FORMIO_PROJECT = 'https://yourproject.form.io';
var FORMIO_API = 'https://api.form.io';

Now, within the /app.js file, we will need to initialize the Formio library with the following.

function config($stateProvider, lockProvider, $urlRouterProvider) {
   Formio.setBaseUrl(FORMIO_API);
   Formio.setAppurl(FORMIO_PROJECT);

   ...
   ...
}

And finally, within the /components/auth/auth.service.js file, we will need to alter the service to set the Form.io JWT token with the one that we provided to the Auth0 Rule.

function authService(lock, authManager) {

    function login() {
      lock.show();
    }

    // Logging out just requires removing the user's
    // id_token and profile
    function logout() {
      localStorage.removeItem('id_token');
      authManager.unauthenticate();
      Formio.setUser(null);
    }

    // Set up the logic for when a user authenticates
    // This method is called from app.run.js
    function registerAuthenticationListener() {
      lock.on('authenticated', function (authResult) {
        localStorage.setItem('id_token', authResult.idToken);
        lock.getProfile(authResult.idToken, function (error, profile) {
          Formio.setToken(profile.user_metadata.formio.token);
          authManager.authenticate();
        });
      });
    }

    return {
      login: login,
      logout: logout,
      registerAuthenticationListener: registerAuthenticationListener
    }
  }

Now, when you log into Auth0, you will automatically connect to a Form.io User within your application creating a seamless authentication between the two platforms!

Auth0 + Form.io Example App

If you would like to see an example application that uses this integration go here.

Go to Form.io + Auth0 Example Project