Implementing basic JWT-based authentication with LoopBack 4 and Docker for complete noobs (1/2)
When I started working on the back-end of my pet project, I dreaded the moment when I had to implement authentication and authorization (like any other developer out there).
LoopBack is a popular IBM library for building API’s fast and deploying them as micro services. It offers out of the box integration with TypeScript, Jest, Mocha and Docker (among others). In this article, I will share with you my noob’s journey of setting up basic JWT-based authentication using LoopBack 4 and MongoDB ran inside a Docker container.
I followed this official LoopBack 4 tutorial for adding JWT-based authentication to an existing app and adapted it to include the Docker/ MongoDB set up (which was the most difficult part for me).
Throughout the article, I will often refer to LoopBack 4 as LoopBack.
When I started working on the back-end of my pet project, I dreaded the moment when I had to implement authentication and authorization (like any other developer out there). I was a bit relieved because I knew I am familiar enough with TypeScript and Node.js to do this with LoopBack 4. But, on the other hand, I was a complete Docker noob and I wanted to run everything in Docker.
Before we move on, let me explain my technical choices.
- Why LoopBack? I needed micro services and I wanted a short(ish) development time*. If I really wanted to do more learning, I would have gone for Flask or Django, but I was confident enough I can handle Node.js and not have to learn too many new things in one go.
- Why Docker? I’m lazy. I don’t want to be bothered installing 100 new programs on my laptop to do development. I want to start Docker and have everything I need there.
Ok, back to the coding.
*let’s not fool ourselves, I wish it would have taken me 2 weeks of intense programming after work, but “real” summer decided to show up — I live in a rainy country, where “real” summer is something you enjoy while you can)
Step 1: Install dependencies
For this project, you will need the following programs installed on your local machine:
- Loopback4 CLI
npm i -g @loopback/cli
Step 2 : Read the documentation
Here is some basic documentation for LoopBack 4:
For this particular tutorial, it’s also good if you skim the LoopBack documentation about controllers, models, relations between models, data sources and repositories.
The simplified structure of a LoopBack app looks something like this (the front-end is not part of the app, I just added it in the diagram for completeness).
The really magical part for me is the data source layer, because LoopBack has many data source connectors written for it that know how to communicate with various database solutions, like MongoDB, PostgreSQL, Redis and so on.
Step 3 : Implementation steps
Ok, so let’s write down the implementation steps:
- Boot a MongoDB instance on localhost through Docker, with a database named test_db. Because we are security mindful, we want to connect to this database with a username and a password that we keep in a local .env file (so we avoid sharing our credentials with the whole wide world when we share our project on GitHub, for example).
- Create a new datasource in our LoopBack project, and connect it to the newly created test_db database.
- Implement the JWT authentication example in the LoopBack 4 tutorial.
- Test that the api endpoints we created work as expected.
And now we finally get to the fun part… let’s write some code!
Step 4 : Create your project
Follow the interactive terminal steps and make your choices of packages to be installed and whether you want yarn instead of npm. From experience, I noticed that yarn is faster than npm, so if you develop a bigger project, you can go for yarn. For our toy project, it doesn’t really matter which one you choose.
Step 5 : Run MongoDB in Docker
This is the step where I got stuck for several days, because I couldn’t figure out for the life of me how to create a new database in MongoDB via Docker (yes, yes, I’m a Docker noob).
For some time, I thought that the LoopBack Mongo connector will auto-magically create a new database for me. But no, creating a new database is Docker’s responsibility, not LoopBack’s.
So, we add a new
docker-compose.yml file in the root directory of our project. Why Docker compose? Because it lets you run multiple containers from one single file. When your project grows, you just run
docker-compose up and you’re ready to go.
docker-compose.yml, you add the following code
If you want a detailed explanation of each line, please go to the article here.
- we use the latest Mongo server image to boot the Docker container
- we use the
.envfile for the MongoDB credentials to be able to log in to the database in the container. Many
docker-composeexamples use the
environmentproperty instead of
env_file, and that’s fine for examples and toy projects, but not ok for actual development
- the MongoDB port will be forwarded from the container to our localhost port 27017
- the entry point for our MongoDB container is the shell script
In our root directory we will then add the 2 files we need:
WARNING: (I’m sharing this with you for illustration purposes, but you should never share/commit this file. This should be kept local and added to .gitignore. In the README.md of your repo, you can instruct the people cloning your code to create their own local .env file and add their own credentials there).
This is where we customize our Docker MongoDB instance.
In this script, we do the following:
- Use the credentials from the
.envfile to create a new user
- This user will be created in our
test_dbdatabase. In case this database doesn’t exist, MongoDB will know to create it by default.
- We assign various roles to the MongoDB user we create (
readWriteis enough for what we need, but I also wanted to see the database users, so I added more roles).
Now we need to start the Docker container to make sure everything works as expected.
If we don’t want to see the logs, we can run the command
docker-compose up -d (-d comes from detached process = running in the background). But we want to see the logs, because there we can see this:
So there we have it! We successfully created a new user and a new database in a Docker container. In Part 2 of this guide, we will finally get to play with LoopBack 4.