Adding authentication to a LoopBack App

NSerus
3 min readApr 15, 2021

Hello Peppos!!

Today we are going to add Authentication to the Todo App that we previously made to make the application’s API more secure.

LoopBack4 has a Authentication package with the name of @loopback/authentication in which secures your app’s API’s endpoints with custom authentication strategies and an @authenticate decorator.

This tutorial is based on the tutorial on the LoopBack4 Website.

Take a look on the final project if you have any problems or errors in the making of this tutorial.

JSON Web Token Approach

An overview of the JSON Web Token Approach

In this authentication method, when the user provide the credentials to a login endpoint, the server creates a JWT token and returns it as a response (upper part). That token is a string that consists of 3 parts:

  • A Header
  • A Payload
  • A Signature

The header and the payload are signed with secret and the parts are separated by a period

After logging in, when the user attemps to access a protected endpoint, the token must be used in the Authorization header. The server verifies if the token is valid, and allows access to the protected endpoint.

To install the authentication package on the project just run the command:

npm i --save @loopback/authentication @loopback/authentication-jwt

Bind JWT Component in the Application

To bind the authentication component, add the following code to src/application.ts :

// ---------- ADD IMPORTS -------------
import {AuthenticationComponent} from '@loopback/authentication';
import {
JWTAuthenticationComponent,
SECURITY_SCHEME_SPEC,
UserServiceBindings,
} from '@loopback/authentication-jwt';
import {DbDataSource} from './datasources';
// ------------------------------------

export class TodoListApplication extends BootMixin(
ServiceMixin(RepositoryMixin(RestApplication)),
) {
constructor(options: ApplicationConfig = {}) {
//...
// ------ ADD SNIPPET AT THE BOTTOM ---------
// Mount authentication system
this.component(AuthenticationComponent);
// Mount jwt component
this.component(JWTAuthenticationComponent);
// Bind datasource
this.dataSource(DbDataSource, UserServiceBindings.DATASOURCE_NAME);
// ------------- END OF SNIPPET -------------
}
}

Create the UserController for login

In the UserController, we are going to create3 endpoints:

  • /login for users to provide credentials.
  • /signup for users to sign up.
  • /whoami for showing who the user currently is.

Create the controller using lb4 controller command with the empty controller option.

$ lb4 controller
? Controller class name: User
Controller User will be created in src/controllers/user.controller.ts

? What kind of controller would you like to generate? Empty Controller

create src/controllers/user.controller.ts
update src/controllers/index.ts

Controller User was created in src/controllers/

Add endpoints in UserController

For UserService which verifies the credentials, we are going to use the default implementation in @loopback/authentication-jwt . Therefore, the constructor injects the MyUserService from this extension.

The controller’s location is in /src/controllers/user.controller.ts.

// ---------- ADD IMPORTS -------------
import {inject} from '@loopback/core';
import {
TokenServiceBindings,
MyUserService,
UserServiceBindings,
UserRepository,
} from '@loopback/authentication-jwt';
import {TokenService} from '@loopback/authentication';
import {SecurityBindings, UserProfile} from '@loopback/security';
import {repository} from '@loopback/repository';
// ----------------------------------

constructor(
@inject(TokenServiceBindings.TOKEN_SERVICE)
public jwtService: TokenService,
@inject(UserServiceBindings.USER_SERVICE)
public userService: MyUserService,
@inject(SecurityBindings.USER, {optional: true})
public user: UserProfile,
@repository(UserRepository) protected userRepository: UserRepository,
) {}

Now you can implement yourself the 3 endpoints, or you can scroll down to the end of this tutorial to see the final result of user.controller.ts .

Protect the Todo API’s

To protect other endpoints that we have. Go to src/controllers/todo.controller.ts and imply add @authenticate('jwt') before the TodoController class.

// ---------- ADD IMPORTS -------------
import {authenticate} from '@loopback/authentication';
// ------------------------------------
@authenticate('jwt') // <---- Apply the @authenticate decorator at the class level
export class TodoController {
//...
}

If there are particular API that you want to make it available to everyone without authentication, you can add @authenticate.skip() before that function.

The result of the UserController

--

--