Over a million developers have joined DZone.

Planet-Scale Authentication With Auth0 and Azure DocumentDB

In this article you will learn how to integrate Auth0 with the fast and scalable Azure DocumentDB as a custom database connection and use it in your Auth0 applications.

· Database Zone

Build fast, scale big with MongoDB Atlas, a hosted service for the leading NoSQL database. Try it now! Brought to you in partnership with MongoDB.

Auth0 offers a highly performant and secure user store to maintain your users’ profiles. It is also a common solution if you want to store your users’ login information in your own database where you keep all of your application's data; in this case, Auth0 provides you with several identity providers you can use to integrate. One such database is Azure DocumentDB, a blazing-fast NoSQL service for highly available and globally distributed applications.

During this article, we will guide you into integrating Auth0 and Azure DocumentDB so your users' profiles are stored on your cloud NoSQL database.

Authentication Integrated

Let’s start by noting the diversity of custom database identity providers that Auth0 supports.

This list includes MySQL, SQL Server (both on-premises and on Azure), PostgreSQL, ASP.NET Membership Providers, any Basic Auth web service and MongoDB. We will focus on this last one since Azure DocumentDB now supports the MongoDB protocol.

Auth0 custom providers list

You can see the full Custom Database Identity providers' documentation in the official docs.

The integration is achieved by customizable Node.js scripts that can be coded directly on Auth0’s configuration dashboard manually or using a wide array of templates.

To sum up, we will be using the MongoDB protocol supported by Auth0 identity provider to connect to our Azure DocumentDB and store/retrieve our users' information by custom Node.js scripts.

Creating Our Database

As we mentioned before, Azure DocumentDB supports the creation of databases that support the MongoDB protocol (as of the writing of this article, this feature is in preview). We must access the Azure Portal and filter for DocumentDB services to find the version with MongoDB support:

Searching the Azure PortalCreating our Azure DocumentDB service

Once created, we will be able to access our connection string credentials on the instance blade. We need to take note of these values because we will use them later on the integration:

Obtaining connection string

After creating our service, we will proceed to create a Database and a Collection to store our data. If you are not familiar with the Database and Collection concepts for NoSQL databases, a Database can hold multiple Collections and each Collection will store Documents (in JSON format). You will be billed for each Collection, so plan your distribution accordingly.

You can review the complete concept diagram in the official documentation.

We will create an "auth0" database:

Creating a database

And a "users" collection:

Creating a collection

Azure DocumentDB lets you define a dynamic and scalable throughput you can increase later as your application demands.

Establishing the Integration

In this step, we will use the connection string information we collected in the Azure Portal to create a custom database provider. In your Auth0 Dashboard, you will see a Connections > Database configuration section:

Auth0's Dashboard Connections menu

Once there, you can Create a DB Connection:

Create Db Connection

You will be asked for a name:

Setting up Connection name

Once created, we will go to the Custom Database tab and enable the "Use my own database" toggle, which will activate the lower Database Action Scripts section.

The Auth0 editor allows us to define global variables to reuse on all our Node.js scripts. Let's start by setting a global connection string; on the Settings subsection, we create a "ConnectionString" key and paste the Connection String value we obtained from the Azure Portal with the added database name.

Your copied string looks like this:

mongodb://<your_service_name>:<your_password>==@<your_service_name>.documents.azure.com:10250/?ssl=true

We will add the database name after the port, like this:

mongodb://<your_service_name>:<your_password>==@<your_service_name>.documents.azure.com:10250/auth0?ssl=true

Setting up global variable

In our Node.js scripts, we can access this value by the global variable configuration.ConnectionString.

Now, we will define our custom Login, Create, Verify, Change Password and Delete scripts using our predefined variable:

Login

function login (email, password, callback) {
  mongo(configuration.ConnectionString, function (db) {
    var users = db.collection('users');
    users.findOne({email: email}, function (err, user) {


if (err) return callback(err);

      if (!user) return callback();

      if (!bcrypt.compareSync(password, user.password)) {
        return callback();
      }
      callback(null,   {
        user_id:      user._id.toString(),
        nickname:     user.nickname,
        email:        user.email
      });

    });  
  });
}

Create

function create (user, callback) {
  mongo(configuration.ConnectionString, function (db) {
    var users = db.collection('users');

    users.findOne({ email: user.email }, function (err, withSameMail) {

      if (err) return callback(err);
      if (withSameMail) return callback(new Error('the user already exists'));

      user.password = bcrypt.hashSync(user.password, 10);

      users.insert(user, function (err, inserted) {  
        if (err) return callback(err);
        callback(null);
      });
    });
  });
}

Verify

function verify (email, callback) {
  mongo(configuration.ConnectionString, function (db) {
    var users = db.collection('users');
    var query = { email: email, email_verified: false };

    users.update(query, { $set: { email_verified: true } }, function (err, count) {
      if (err) return callback(err);
      callback(null, count > 0);
    });
  });
}

Change Password

function changePassword (email, newPassword, callback) {
  mongo(configuration.ConnectionString, function (db) {
    var users = db.collection('users');

    var hashedPassword = bcrypt.hashSync(newPassword, 10);

    users.update({ email: email }, { $set: { password: hashedPassword } }, function (err, count) {
      if (err) return callback(err);
      callback(null, count > 0);
    });
  });
}

Delete

function remove (id, callback) {
  mongo(configuration.ConnectionString, function (db) {
    var users = db.collection('users');
      var o_id = new mongo.ObjectID(id);
      users.remove({ _id: o_id }, function (err) {
      if (err) return callback(err);
      callback(null);
    });
  });
}

And we can test the connection by running the Create script from within the interface:

Testing the connection

If we query the content of the Azure DocumentDB collection through the Azure Portal, we will find our created user:

{
    "_id": {
      "$oid": "57f2983189b7550100e909e4"
    },
    "tenant": "ealsur",
    "connection": "DocumentDB",
    "email": "ealsur@ealsur.com.ar",
    "password": "$2a$10$hiSfzkpLjQUXivV4AvdakOCsTqDAYeSAx1Dn2HfPW6XuU28i5wgpq",
    "debug": true,
    "id": "57f2983189b7550100e909e4",
    "_rid": "u11qAL9JdQATAAAAAAAAAA==",
    "_self": "dbs/u11qAA==/colls/u11qAL9JdQA=/docs/u11qAL9JdQATAAAAAAAAAA==/",
    "_etag": "\"08007436-0000-0000-0000-57f298320000\"",
    "_attachments": "attachments/",
    "_ts": 1475516462
}


As you can see, this is a plain JSON object that is readable through any application-consuming collection.

Finally, we can create a new Client Application and define that we will use our custom Azure DocumentDB database on the Connections configuration.

For a detailed concept explanation, you can read the official Applications documentation.

Defining the Application connection

This will let our Client Application access and use the DocumentDB identity provider.

User Profile Customization

Since Azure DocumentDB uses JSON to store our user profiles, we can take advantage of this dynamic data format and customize our users' profile data during sign-up.

To achieve this, we can use Auth0's Lock and configure the required additional signup fields. This will generate the new fields and store them on our collection as part of the user profile without any extra work.

You can also view the complete Custom Signup documentation for a more detailed explanation.

Conclusion

Auth0’s custom database flexibility lets us use one of the most dynamic and fast NoSQL service offerings available. Azure DocumentDB has the ability to scale and grow as your business or application does in a seemingly easy way.

Now it's easier than ever to get started with MongoDB, the database that allows startups and enterprises alike to rapidly build planet-scale apps. Introducing MongoDB Atlas, the official hosted service for the database on AWS. Try it now! Brought to you in partnership with MongoDB.

Topics:
azure documentdb ,database ,auth0 ,authentication

Published at DZone with permission of Matias Quaranta, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}