“Turn on all security features like two-factor authentication. People who do that generally don’t get hacked. Don’t care? You will when you get hacked. Do the same for your email and other social services, too.” — Robert Scoble
“Extra layer of security” — who doesn’t need it? Is your website having a provision to enable Two-Factor authentication (TFA) for your users? Yes, you would definitely need your user-base to be more secure than just having a password based authentication.
In this tutorial we’ll learn how to easily enable and integrate the 2-Factor Authentication in an Angular-7 app using Node JS as the back-end technology along with Google Authenticator, that provides Time based — One Time Password(TOTP). By the end of this post, you will be able to create an application that has a simple login and registration feature along with the 2-Factor Authentication.
GitHub repository to be followed: angular-node-mfauth (https://github.com/Narendra-Kamath/angular-node-mfauth)
<a href="https://medium.com/media/138a83424fb4aa6cd8e427c828200cd7/href">https://medium.com/media/138a83424fb4aa6cd8e427c828200cd7/href</a>
After having the above mentioned tools being installed, the next step would be to create the API services for the application.
For creating the API services, we would be using the minimal and flexible web framework for Node.js called as Express.js. Let us now create a dedicated directory ‘back-end’ for our server-side app and navigate into that folder in the terminal/ command prompt and install the required project dependencies.
> mkdir back-end
> cd back-end
> npm init -y
> npm install --save express body-parser cors qrcode speakeasy
Now, we have created a directory ‘back-end’ and initialized it as a Node.js project by installing the following dependencies:
We will now create a few API services, with app.js as the main file of execution. For the simplicity of learning process, separation of concerns is followed for the scaffolding of the application.
Folder structure for back-end
The API services will expose the features of login, registration and TFA with the following routes:
<a href="https://medium.com/media/43216c0e3fd70f80294467906a4e50bd/href">https://medium.com/media/43216c0e3fd70f80294467906a4e50bd/href</a>
In this tutorial we wouldn’t be using a Database to store the user object and hence we would be using a common and shared user object on the server side.
<a href="https://medium.com/media/4252f7e0b68885431e923b98063f0958/href">https://medium.com/media/4252f7e0b68885431e923b98063f0958/href</a>
2. Registration service: The registration of a user in the application would be just to add the username and password to the userObject as well as to reset the already existing userObject information. Since the login and registration modules are made just for the demonstration purpose, the application will support only a single user login and registration.
<a href="https://medium.com/media/be06514234aeb2d4bcc54909180e9ecd/href">https://medium.com/media/be06514234aeb2d4bcc54909180e9ecd/href</a>
3. TFA service: This service is to provide a feature for the setup of the two factor authentication along with the verification of the T-OTP code generated by Google Authenticator. The service would include the functionalities to GET the existing TFA configuration as well as to enable or disable the TFA for a userObject.
<a href="https://medium.com/media/e696b50a8159e0caefa31021db7caab9/href">https://medium.com/media/e696b50a8159e0caefa31021db7caab9/href</a>
The above mentioned routes are exported for a common integration and single entry file in the root directory ‘app.js.’ This would start the express generated HTTP server on the localhost with port number 3000.
<a href="https://medium.com/media/cc09e205798d56f36e661da3dd1381b2/href">https://medium.com/media/cc09e205798d56f36e661da3dd1381b2/href</a>
Thus we have setup the server side code for our web application. The server script could be started and let it Rest In its Place ;)
Now the next step would be to create a simple Angular 7 application to consume these created services.
For creating an Angular 7 application, we should first install Angular globally. After installing angular, we’ll create an app by the name ‘front-end’ and we’ll also install the local dependency of ‘bootstrap’ (link the bootstrap.min.css in styles.css) by navigating to front-end directory.
> npm install -g @angular/cli
> ng new front-end
> cd front-end
> npm install --save bootstrap
> ng serve
After successfully creating the angular app and launching the app server, we’ll generate a few components, guards and services required for the application.
For the purpose of demonstration we would be creating a LoginService and two guards — ‘Auth Guard’ and ‘Login state management Guard.’
> ng g s services/login-service/login-service --spec=false
> ng g g guards/AuthGuard
> ng g g guards/Login
The guards generated here are the CanActivate guards. The login-service would include the HTTP calls to the services created at back-end.
<a href="https://medium.com/media/3859a27ac903b1803199b61ddf0b23ae/href">https://medium.com/media/3859a27ac903b1803199b61ddf0b23ae/href</a>
The AuthGuard would restrict the user to navigate to the Home page without login.
<a href="https://medium.com/media/08a5da3ebdb3ee9fe05c42ff5f375a83/href">https://medium.com/media/08a5da3ebdb3ee9fe05c42ff5f375a83/href</a>
The login-guard would not allow the user to navigate to login or registration page if the user is already logged-in.
<a href="https://medium.com/media/e7ea9fdaf13c0311e4a90e02fa46e929/href">https://medium.com/media/e7ea9fdaf13c0311e4a90e02fa46e929/href</a>
Since we have completed with the backbone for our application by creating the services and guards, we’d now create a few major components and also configure the routing for the application.
> ng g c components/header --spec=false
> ng g c components/home --spec=false
> ng g c components/login --spec=false
> ng g c components/register --spec=false
After creating the necessary components for the app, we’ll now configure the routing for the app, by linking the respective guards for activating the routes.
<a href="https://medium.com/media/124fb605fd858edd14109016b273da0d/href">https://medium.com/media/124fb605fd858edd14109016b273da0d/href</a>
Let’s now have some code done on the components created, before which we have to remove the default code in app.component.html, and we’ll just mention the common header component and the router-outlet.
<a href="https://medium.com/media/dcbaf8c95868871f80a79684a6841622/href">https://medium.com/media/dcbaf8c95868871f80a79684a6841622/href</a>
<a href="https://medium.com/media/860e16260fdad1a3367a59244732bcf5/href">https://medium.com/media/860e16260fdad1a3367a59244732bcf5/href</a>
In the background of this HTML, we would require the *.ts file as well, for the header component.
<a href="https://medium.com/media/fe3517d7cd513cb91a8b23e95682c3ba/href">https://medium.com/media/fe3517d7cd513cb91a8b23e95682c3ba/href</a>
2. Login Component: This is a simple component to accept the username, password and the AuthCode (if TFA is enabled) from the user and to verify it with the back-end services. If the user information is valid, then the user will be navigated to the HomeComponent.
<a href="https://medium.com/media/15b8ec18afeb6af06a7e382c531ee92a/href">https://medium.com/media/15b8ec18afeb6af06a7e382c531ee92a/href</a>
We would also be verifying the status received from the back-end to display appropriate messages to the user.
<a href="https://medium.com/media/267a7a98a38f1c5408a8ea7fe73eadcc/href">https://medium.com/media/267a7a98a38f1c5408a8ea7fe73eadcc/href</a>
3. Registration Component: As stated earlier in this post, we would be able to register a single user in the whole application and we would require the user to enter any username and password (certainly the one that you would remember :P ) for the registration purpose.
<a href="https://medium.com/media/b132bd3fa27d41a1f4f2cbbeaf40dc39/href">https://medium.com/media/b132bd3fa27d41a1f4f2cbbeaf40dc39/href</a>
In case you forget your username or the password provided for the application or in case if you miss the TFA secret key in your device, then simply provide a new username and password in the registration page (basically you would be resetting the userObject :P).
<a href="https://medium.com/media/4c2a3bdf827a4d3774f8d4f2639b05a0/href">https://medium.com/media/4c2a3bdf827a4d3774f8d4f2639b05a0/href</a>
Login and Registration page
Once the user is registered and logged in with the username and password, the user will be provided with an option to enable or disable the Two-Factor Authentication in the HomeComponent.
4. Home Component: In this component, we would be allowing user to setup and verify the TFA. As soon as you land on this page, there will be an option to setup the TFA, where the QR-Code, which is to be scanned in the Google Authenticator app. As soon as you scan, the T-OTP (TFA element) linked with the userObject will be included in the Google Authenticator app. The AuthCode will be displayed on time basis in the app and the same code should be entered in order to verify and enable TFA for the userObject.
<a href="https://medium.com/media/27763332fe9df92644e44fba0aaf883d/href">https://medium.com/media/27763332fe9df92644e44fba0aaf883d/href</a>
If the user has enabled TFA, then the current settings with the QR-Code and Secret Key will be displayed, along with an option to disable the TFA linked with userObject.
<a href="https://medium.com/media/6d93e7d0ca6fe194064731bdc3a5cba6/href">https://medium.com/media/6d93e7d0ca6fe194064731bdc3a5cba6/href</a>
Setup TFA and Current Settings of TFA
Hurray!! If you have reached till this length of the post, then you have successfully learnt of how to easily integrate the Two-Factor Authentication in your Angular 7 application. For any debugging process, you may look at the console of either the front-end application or the back-end application. Hope it was easy to integrate Two-Factor Authentication with your Angular 7 app… Cheers!!
Kindly share your views in the responses section :) Thank you!