Complete user management system with LoopBack 2.x APIs & AngularJS - Part 1

In the previous post of LoopBack 2.x -The most comfortable framework for creating Node.js REST APIs, we discussed how we can develop a REST APIs in no time with LoopBacks and how it works in basis along with its models and other components. In this post, we will start developing a full stack user management system with LoopBack REST APIs and AngularJS.
I think this is the art happened where the backend and frontend meet, being the full stack. Both parts are working fantastic on their own until they start talking to each other and the fight never ends. Firstly, we will go with the difficult one that LoopBack makes it easy for us, the REST APIs to manage users.

I assume you have a working node.js and mongoDB working environment in your machine. If you dont have one, you can take a look at Installing Node.js and MongoDB.

Creating REST APIs

To start developing with LoopBack, you just simply need to install strongloop module by using the following npm command in your terminal.

Installing LoopBack

$ npm install -g strongloop

The installation of strongloop module allows us
1. Scaffolding and modifying LoopBack app with the slc command-line.
2. AngularJS client SDK to create client script for front-end app.
3. StrongLoop Process Manager for load balancing, monitoring and multi-host deployment.

Concepts

What we will do in this tutorial is to create a basic kick starter application that will handle all features related to users authentication and authorisation as shown in following list:

Features

  1. Register a new user
  2. Login a user
  3. Logout a user
  4. Send a verification email when a new user registers
  5. Forgot and reset password

Types of users

  1. guest
  2. owner
  3. team member
  4. administrator

Model definition and other access control list will be defined after we have a basic working app. We should slowly approach this procedures as it is a long journey.

Cloning LoopBack Example User Management

We will use an existing LoopBack example for our User Management application. It will save a lot of time and let us study the official LoopBack code a lot.

So, clone the loopback-example-user-management from this link, install the node packages and start the app by using following commands in your terminal.

$ git clone git@github.com:strongloop/loopback-example-user-management.git user-management-lb
$ cd user-management-lb
$ npm install
$ node .

What includes in the example

After cloning the example, let's take a look what's inside.

user model

The example includes a user model named user, which extends the Loopback built-in User model, under common/models directory. Along with user.json model definition file, user.js file is added to do logic works such as sending emails and password reset in this example.

Routes defined

The app's routing system is configured by Express JS in the server/boot/routes.js for the following routes:

  1. GET / => render login view
  2. GET /verified => render verified view
  3. POST /login => login a user with email & password
    • if ERROR, render response view with Login failed message
    • If SUCCESS, render home view & RETURN request's email with an access token.
  4. GET /logout => logout a user with access token id
    • if NOT ACCESSTOKEN, RETURN 401 status
    • ELSE, logout & REDIRECT request to /
  5. POST request-password-reset => send an email with instructions to reset an existing user's password
    • if ERROR, RETURN 401 status
    • ELSE, render response view with Password reset requested
  6. GET /reset-password => render password reset form
    • if NOT ACCESSTOKEN, RETURN 401 status
    • ELSE, render password-reset view with request's access token
  7. POST /reset-password => reset the user's password
    • if NOT ACCESSTOKEN, RETURN 401 status
    • if NOT PASSWORD MATCH, RETURN password not match 400 status
    • ELSE, updateAttribute password and render response view with password reset success.

Views or pages to render

There are 5 views in total, written in EJS template framework in this example as following:

  1. home.ejs, the main page where is redirected after login success
  2. login.ejs contains Login, Register and Request Password Reset form
  3. password-reset.ejs contains Password Reset Form
  4. response.ejs is responsible for showing variable message from server response
  5. verified.ejs shows registration verified successfully message

Model configuration file

In model-config.json contains all configuration of built-in LoopBack models and custom model named user with lower u that is extended from User model.

Model and email datasources

The datasouces.json defines two main datasources of our app, models and email. In model datasource, we will add a little trick ourself to our memory datasource connector as following:

"db": {
    "name": "db",
    "connector": "memory",
    "file": "data.json"
  }

The extra line "file": "data.json" allows you save all of our application model data stored in memeory datasource connector into a data.json under the app root directory. Then, we can constantly watch the changes in data easily without opening mongod or in terminal screen.

As I am going to use Gmail for this example, the email datasource can simply be configured by changing username and password in datasoruces.json file and by allowing less secure app access to your Gmail at this link. For other email types, you can take a look here.

Testing the app

That is. We are all done our 5 basic authentication features that was defined above. Now, let's watch and test how LoopBack is too good at handling user authentication starting from User Registration.

You can do the test via either the LoopBack explorer at http://0.0.0.0:3000/explorer/ or forms at http://0.0.0.0:3000/.

In this tutorial, I will perform testing by using forms. It would be such as waste of beautiful ejs templates if we don't use them. :)

1. Register a new user

At http://0.0.0.0:3000/, enter your email (actual one to enable receiving an email from the app) and password in the Sign up form, and click Sign up button.
Sign up form

The results

  1. The form's POST method to /api/users route created a new user row in user model along with verificationToken.
  2. After creating a new user, it triggered the remote hook method defined in user.js to send a verification registration email and render Signed up successfully response message to user.
  3. You can see there is one new user added to user model in data.json file.
  4. Your registered email will receive an email with an link to verify your account.

2. Verify a signed up user

Click on the link that you received in the verification email.

The results

  1. The route /api/users/confirm?uid=?&redirect=?&token=? triggered the built-in account verification method of LoopBack.
  2. The newly registered user will be verified and will be redirected to verified page (by GET /verified method from routes.js) as following screenshot.

Registration verified successfully

3. Login a user

Again at http://0.0.0.0:3000/, fill your login details at Login form and click *Login * button.

Login form

The results

  1. The form's POST method to /login route is handled by POST /login method from routes.js.
  2. It triggered built-in User login method by passing request's email and password.
    2.1. If there is an error, it will render login failed response message to user to try again.
    2.2. If login successes, we will be redirected to home page that shows our logged in email and accessToken.

4. Logout a user

Just click Logout button after logged in and we will see the results. :P

5. Forgot password

After logged out, enter your registered email in the Reset password form at the home page.
Reset password form

The results

  1. The form's POST method to /request-password-reset route is handled by POST /request-password-reset method from routes.js.
  2. It triggered built-in User resetPassword method by passing request's email.
    2.1. If there is an error, it will rend an error status of 401.
    2.2. If success, an email that contains a link to reset the password is sent and response page is rendered showing a message Password reset requested and check your email.

6. Reset password

Click on the password reset link from the email that you received from Reset Password Form. The reset password page is opened, which contains Password reset form. Enter twice your new password and click Reset password button.

The results

  1. The form's POST method to /reset-password?access_token=<%= accessToken %> route is handled by POST /reset-password.
  2. If access_token is not included in the request, it will send 401 error status.
  3. If the new password and confirmation password are matched, a user is searched by the request's userId and updated its password attribute.
  4. If there is no error, the user will be responded with an Password reset success message.

Troubleshooting

The only error you may likely encounter in installing strongloop module is permission denied to npm folder. In order to solve this,

  1. Firstly, find the path to npm's directory by entering npm config get prefix command in terminal. Usually, /usr/local is the default path. Do not proceed to step to step 2, if the returned path is just /usr

  2. Change the ownership of the npm's directories to the name of the current user (your username of course): sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}

This will make the current user gets full permission on all sub-folders used by npm and some other tools.

I hope this tutorial might help you a lot easier way to catch up the LoopBack user management example. In this tutorial, we finished the most demanding features of user authentication such as registering, logging in and out, sending verification email and resetting password with optimal security and performance.

But this is not our journey ends. In the next tutorial, we will continue the authorisation part of our User Management app using LoopBack advanced features, such as Access Control List, to control multi-level user authorisation.

Thank you for taking your time reading this post and your sharing makes my day if you enjoy this post.

Nay Win Myint

Founder and CEO of Pancasikha Music Streaming Provider, JavaScript full-stack and Android developer and Graphic designer.

Rangoon, Myanmar