JSON Web Auth Using Angular 8 And NodeJS

Introduction 

 
This article discusses the JSON Web Token (JWT) and its authentication into your Angular 8 project with a secure backend API running on Node.JS. The security that will lie beneath the interfacing will be JWT as it is a secure and competent way to authenticate users by means of API endpoints.
 

What are JSON Web Tokens?

 
JSON Web Token is an open standard or RFC Standard (Request for Comments). It comprises of a best-practice set of methodologies which describes a compact and autonomous way for securely transmitting information between parties as a JSON object. This information is digitally signed or encrypted and hence it can be simply verified and trusted. For this purpose, a secret key such as an HMAC algorithm is set or a public/private key pair is generated using RSA or ECDSA.
 

Why are JSON Web Tokens useful?

 
JWT offers the most secure way for authenticating the integrity of the exchange of information between the client and the server. It is adapted for verification so in the case of any violation or breach, the token will not verify or expire based on time.
 
Moreover, the benefits of JSON Web Tokens (JWT) weigh more compared to Simple Web Tokens (SWT) or Security Assertion Markup Language Tokens (SAML) so JWT
can be preferred over the other two.
 
Let's take a glance at the theory in practice for JSON web authentication using Angular 8 and NodeJS.
 
Here, Angular 8 will be used on the frontend while Node.JS server on the backend. First, an interceptor will be formed on the Angular side. An interceptor can break any HTTP request sent from Angular, replicate it, and insert a token to it before it is sent at last.
 
All the requests obtained will first be broken and replicated or cloned on the Node.JS side. Then, the token will be extracted and authenticated. If the verification is successful, the request will be forwarded to its handler for a specific response. If the authentication fails, all remaining requests will be invalid and a 401 unauthorized status will be sent to Angular.
 
All requests will be verified for a 401 status in the interceptor of the Angular App and for such a request, the token will be removed which is stored at Angular. The user will be logged out of all sessions and will land on the login screen.
 
Let’s get started.
 
The Angular App is created at the frontend followed by interceptor creation.
  1. ng new angFrontend  
Then, the Interceptor.
  1. ng generate service AuthInterceptor  
Now go to src/app/app.module.ts
 
Here, HTTP Module is imported for HTTP Calls to obtain global access.
  1. import { BrowserModule } from '@angular/platform-browser';  
  2. import { NgModule } from '@angular/core';  
  3.   
  4. import { AppRoutingModule } from './app-routing.module';  
  5. import { AppComponent } from './app.component';  
  6.   
  7. import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';  
  8. import { AuthInterceptorService } from './auth-interceptor.service';  
  9. import { HomeComponent } from './home/home.component';  
  10.   
  11. @NgModule({  
  12.   declarations: [  
  13.     AppComponent,  
  14.     HomeComponent  
  15.   ],  
  16.   imports: [  
  17.     BrowserModule,  
  18.     AppRoutingModule,  
  19.   
  20.     HttpClientModule  
  21.   ],  
  22.   providers: [  
  23.     { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptorService, multi: true }  
  24.   ],  
  25.   bootstrap: [AppComponent]  
  26. })  
  27. export class AppModule { }  
  28.   
  29. Now open the interceptor service class and then go to src/app/auth-interceptor.service.ts:  
  30. import { Injectable } from '@angular/core';  
  31. import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse } from '@angular/common/http';  
  32. import { catchError, filter, take, switchMap } from "rxjs/operators";  
  33. import { Observable, throwError } from 'rxjs';  
  34. @Injectable({  
  35.   providedIn: 'root'  
  36. })  
  37. export class AuthInterceptorService implements HttpInterceptor {  
  38.   intercept(req: HttpRequest<any>, next: HttpHandler) {  
  39.     console.log("Interception In Progress"); //SECTION 1  
  40.     const token: string = localStorage.getItem('token');  
  41.     req = req.clone({ headers: req.headers.set('Authorization''Bearer ' + token) });  
  42.     req = req.clone({ headers: req.headers.set('Content-Type''application/json') });  
  43.     req = req.clone({ headers: req.headers.set('Accept''application/json') });  
  44.     return next.handle(req)  
  45.         .pipe(  
  46.            catchError((error: HttpErrorResponse) => {  
  47.                 //401 UNAUTHORIZED - SECTION 2  
  48.                 if (error && error.status === 401) {  
  49.                     console.log("ERROR 401 UNAUTHORIZED")  
  50.                 }  
  51.                 const err = error.error.message || error.statusText;  
  52.                 return throwError(error);                      
  53.            })  
  54.         );  
  55.   }    
  56. }  
Section 1
 
First, the token from local storage is retrieved. Then the httpRequest req is cloned or replicated and the header is added to it which is “Authorization, Bearer: token”. Hence the token is formed which will be sent in the header of the httpRequest. This method can also be applied to standardize all the requests with the Content Type and Accept header injection.
 
Section 2
 
If there is an error response such as 401 or 402, the pipe guides to catch the error and further logic to de-authenticate the user due to bad or unauthorized requests can be implemented. For other error requests, it simply gives back the error in the call to the frontend.
 
Next, move on to the creation of Backend.
 
Form a Directory for the Server and type in npm init to initialize it as a node project,
  1. mkdir node_server  
  1. cd node_server  
  1. npm init -y  
To install the required libraries, use the command; npm i -S express cors body-parser express-jwt jsonwebtoken
 
Now, let’s generate an app.js in the node_server folder and start coding the backend.
 
Following is app.js and the boilerplate code:
  1. const express       = require('express')  
  2. const bodyParser    = require('body-parser');  
  3. const cors          = require('cors');  
  4. const app           = express();  
  5. const port          = 3000;  
  6. app.use(cors());  
  7. app.options('*', cors());  
  8. app.use(bodyParser.json({limit: '10mb', extended: true}));  
  9. app.use(bodyParser.urlencoded({limit: '10mb', extended: true}));  
  10. app.get('/', (req, res) => {  
  11.     res.json("Hello World");  
  12. });  
  13. /* CODE IN BETWEEN */  
  14. /* CODE IN BETWEEN */  
  15. /* LISTEN */  
  16. app.listen(port, function() {  
  17.     console.log("Listening to " + port);  
  18. });  
Generally, a token is generated in a production app, which is also the route for authenticating the user, the login route. Once successfully authenticated, you will send the token.
  1. //SECRET FOR JSON WEB TOKEN  
  1. let secret = 'some_secret';  
  1. /* CREATE TOKEN FOR USE */  
  1. app.get('/token/sign', (req, res) => {  
  2.     var userData = {  
  3.         "name""Muhammad Bilal",  
  4.         "id""4321"  
  5.     }  
  6.     let token = jwt.sign(userData, secret, { expiresIn: '15s'})  
  7.     res.status(200).json({"token": token});  
  8. });  
As we have a route now, a secret for encoding our data and remember a data object i.e userData. Therefore, once you decode it, you will get back to this object, so storing a password is not a good practice here, maybe just name and ID.
 
Let’s run the application and check the token generated.
  1. node app.js  
Listening to 3000.
 
Being one of the great tools, you can use ‘postman’ to test the routes.
 
JSON Web Auth Using Angular 8 and NodeJS
 
Hence, the first web token is generated successfully.
 
To illustrate a use case, path1 is created and endpoint is secured using JSON Web Token. For this, use express-jwt.
  1. app.get('/path1', (req, res) => {  
  2.     res.status(200)  
  3.         .json({  
  4.             "success"true,  
  5.             "msg""Secrect Access Granted"  
  6.         });  
  7. });  
  8. Express-JWT in motion.  
  9. //ALLOW PATHS WITHOUT TOKEN AUTHENTICATION  
  10. app.use(expressJWT({ secret: secret})  
  11.     .unless(  
  12.         { path: [  
  13.             '/token/sign'  
  14.         ]}  
  15.     ));  
To further illustrate the code, it states that only allow these paths to access the endpoint without token authentication.
 
Now in the next step, let’s try to access the path without a token sent in the header.
 
JSON Web Auth Using Angular 8 and NodeJS
 
It can be seen that path can’t be accessed. It also sent back a 401 Unauthorized, so that’s great. Now let’s test it with the token obtained from the token/sign route.
  1. app.get('/path1', (req, res) => {  
  2.     res.status(200)  
  3.         .json({  
  4.             "success"true,  
  5.             "msg""Secret Access Granted"  
  6.         });  
  7. });  
As you can see, when adding the Bearer Token, access is received successfully. Heading back to Angular, a new component home is created:
  1. ng generate component home  
Now this is home.component.ts file:
  1. signIn() {  
  2.     this.http.get(this.API_URL + '/token/sign')  
  3.       .subscribe(  
  4.         (res) => {  
  5.           console.log(res);  
  6.           if (res['token']) {  
  7.             localStorage.setItem('token', res['token']);  
  8.           }  
  9.         },  
  10.         (err) => {  
  11.           console.log(err);  
  12.         }  
  13.       );      
  14.   }  
  15.   getPath() {  
  16.     this.http.get(this.API_URL + '/path1')      
  17.       .subscribe(  
  18.         (res) => {  
  19.           console.log(res);  
  20.         },  
  21.         (err) => {  
  22.           console.log(err);  
  23.         }  
  24.       );         
  25.   }  
So, on the signIn function, a token is requested and stored it into localstorage. Then on the second function, the path is requested.


Similar Articles