Photo by Barefoot Communications on Unsplash

MongoDB is a Document Object-Oriented database that belongs to the category of NoSQL databases. It allows manipulating structured objects in a BSON (binary JSON) format without a predetermined schema.


You need MongoDB when you build a system that needs to support a massive amount of readers in the database; you need to scale your database horizontally with the growth; you want to store data where model restriction doesn't exist.
In 2019, MongoDB had a market share of 24.6% in the database. It is the most used NoSQL database. Companies like Barclays, Uber, Lyft, Accenture, CircleCI, and Segment use it to handle their most demanding apps in areas like IoT, Gaming, Logistics, Banking, e-Commerce, and Content Management.

Installation

MongoDB has two editions: Community Edition and Server edition
The community edition provides enough features for small and middle applications. Among these features, we can list :

  • Flexible document model.
  • Indexing to make ours queries faster.
  • Real-time aggregation provides powerful ways to access and analyze your data.
  • Replication is beneficial for those who are working in a distributed system.
  • Horizontal scalability with native sharding.

The Enterprise Edition has all the features of the community edition plus:

  • Auditing allows administrators and users to track system activity for deployments with multiple users and applications. In other words, you can have the history of CRUD operations, schema changes, Authentication, and Authorization.
  • In-Memory Storage Engine.
  • LDAP Proxy Authentication and LDAP Authorization.
  • Kerberos Authentication.

At the time I'm writing this article, we are on version 4.4, and we will use the community edition that is free and enough for our use case.

Follow the installation tutorial on the MongoDB website according to your operating system. Once completed, we can continue with the steps below.
For mac users with Intel processors, here command to run:

# Install XCode Command Line Tools
xcode-select --install

# download the official Homebrew formulae for MongoDB and Database tools
brew tap mongodb/brew

# Verify that your system meets all the installation prerequisites
brew tap | grep mongodb

# Install MongoDB
brew install mongodb-community@4.4

# Start MongoDB as a MacOS service
brew services start mongodb-community@4.4

# Start Mongo Shell to make sure everything works
mongo

The configuration file is located at: /usr/local/etc/mongod.conf

Create user and database

By default, Authentication is disabled, and you just have to type mongo to be inside the database.

  • View all databases: show databases
  • Select a database: use <database_name>
  • View collections of a database: show collections

It is good for development or testing environment, but when you are in production with customers data stored inside, it's mandatory to restrict access to the database by:

  • Identifying all the users who connect to the database; it's called Authentication.
  • Restrict actions an authenticated user can do in the database; it's called Authorization.

Built-in roles

MongoDB comes with built-in roles that will help define restrictions across the database. The picture below shows available roles:

mongo-auth-built-in-roles
List of MongoDB built-in roles

You can restrict using these roles, for example:

  • A read role for a Data Scientist who needs to read data to generate statistics.
  • A readAnyDatabase for a Data scientist who needs to aggregate data from many databases to generate statistics.
  • readWrite and dbAdmin for the backend of a web application with one database. The dbAdmin is useful when you use an ORM that creates the collection in the database from your classes/entities model.

An important thing to note is that the roles cited above are created by combining other roles that can also be given to a user.


Let's imagine we have a worker who will do the backup of our database periodically. According to the table of roles above, we will need to create a user with a role root for the worker to backup and restore our DB, but it is too much because we are also giving all the accesses to this user. To avoid that, you can only give the role backup and restore to this user.
Keep this in mind for when you will need to give a specific role to a user.

You can also create your custom role by combining many built-in roles.

Enable Authentication

Before that, we need to create the root user; otherwise, you can do nothing after the Authentication is enabled. So, inside the mongo shell, create the root user:

use admin
db.createUser({ user: "rootUser", pwd: "rootUserPwd", roles: ["root"]})

We select the database admin and we create a user named rootUser with the password rootUserPwd and finally, grant to him the role root.
Now exit from the mongo shell by typing exit

To enable Authentication, open the config file /usr/local/etc/mongod.conf and add at the end of the file:

security:
  authorization: enabled

Save the file, then exit and restart the MongoDB server.

brew services restart mongodb/brew/mongodb-community

As the picture shows, we get an error if we create a user with a simple read role.

mongo-auth-create-user-error
Failed to create user because Authentication is required

Authenticate user

Here is the command to connect with MongoDB

mongo --port 27017 -u "rootUser" -p "rootUserPwd" --authenticationDatabase "admin"

Now we will create a user and give him role readWrite and dbAdmin on a new database called blog. We will connect with this user, create a collection called posts and make sure we can write and read what we just created.

use blog

db.createUser({ user: "blogUser", pwd: "blogUserPwd", roles: [{ role: "dbAdmin", db: "blog" }, { role: "readWrite", db: "blog" } ]})

exit

The user is now created. Let's continue with the next steps:

mongo --port 27017 -u "blogUser" -p "blogUserPwd" --authenticationDatabase "blog"

use blog

db.createCollection("posts")

show collections

db.posts.insertOne({ title: "Mongo Auth", readCount: 0, tags: ["nosql", "db"] })

db.posts.find()

db.posts.deleteMany({ "title" : "Mongo Auth" })

db.posts.find()

You will get this output:

mongo-auth-crud

We have set up Authentication on a MongoDB Database and advise you to take the habit to use it as is even in the development and test environment.

Hope you find it very helpful to you! See you on Twitter for any questions.