How To Build Authentication in Angular Using Node and Passport
Tags: angular, node, javascript, passport
Published: 2019-11-19 15:47:22

---
title: How To Build Authentication in Angular Using Node and Passport
published: true
description: Passport.js provides a simple authentication middleware that you can use with Node.js. We explore how to use it to easily add authentication to an Angular app.
tags: angular, node, javascript, passport
canonical_url: https://blog.jscrambler.com/setting-up-authentication-using-angular-node-and-passport/
cover_image: https://blog.jscrambler.com/content/images/2019/10/jscrambler-blog-how-to-build-authentication-passport-angular-node-1.jpg
---

In this tutorial, you'll learn how to build an authentication in your Node Angular app using Passport.js.
 
The tutorial assumes the reader to be familiar with creating a basic application using Angular and Node.js Express framework. You'll implement the Authentication using Passport on top of an Angular Sales Dashboard application covered in a previous [tutorial](https://blog.jscrambler.com/creating-a-sales-dashboard-using-angular-and-google-charts).

The source code from this tutorial is available on [GitHub](https://github.com/JscramblerBlog/passport-angular-node).

## Why Authentication?
Why do you need authentication? Well, adding some kind of authentication makes your application secure and prevents unauthorized access.

Authentication can be done with a username and password or it can be a One-Time Password (OTP) sent to your phone. Using existing user information from popular social networks such as Google, Facebook, etc. is another way to add authentication.

## What is Passport.js?
Passport.js is a middleware that can be easily used in your Node.js application. It helps to authenticate using username and password, Facebook, GitHub, etc. 

From the official documentation,

> Passport is authentication middleware for [Node.js](https://nodejs.org/). Extremely flexible and modular, Passport can be unobtrusively dropped into any [Express](https://expressjs.com/)-based web application. A comprehensive set of strategies support authentication using a username and password, Facebook, Twitter and more.


## Getting Started

Let' start by cloning the source code of the Angular Sales Dashboard app from its [GitHub repository](https://github.com/JscramblerBlog/angular_dashboard).
```bash
git clone https://github.com/JscramblerBlog/angular_dashboard
```
Navigate to the project directory and install the required dependencies.
```bash
cd angular_dashboard
npm install
```
Once the dependencies have been installed, start the Angular application server.
```bash
npm start
``` 
You'll have the Angular application running on `localhost:4200`.

## Setting Up Authentication API

To set up the authentication API, you need to create a Node project.
```bash
mkdir node-api
cd node-api
npm init
```
Enter the required details and you will have the Node project setup. Next, install the Express framework for creating the API.
```bash
npm install express --save
```
Once you have Express installed, create a file called `app.js` and add the following code to it:
```javascript
const express = require('express');
const app = new express();

app.post('/authenticate', (req, res) => {
    res.status(200).json({"statusCode" : 200 ,"message" : "hello"});
});

app.listen(3000, () => {
    console.log('App running at 3000')
})
```
That's the basic Express server with an endpoint. You now need to add a custom middleware to the `/authenticate` route.

### What is a Middleware?

A middleware is a function that can intercept a request. It has access to the request, response objects and a `next` function. This `next` function, when invoked, executes the next middleware.

Let's add a custom middleware to the route.
```javascript
const auth = () => {
    return (req, res, next) => {
        next()
    }
}

app.post('/authenticate', auth() , (req, res) => {
    res.status(200).json({"statusCode" : 200 ,"message" : "hello"});
});
```
The `auth` custom middleware does nothing but invoke the next middleware by calling `next`. Inside the `auth` middleware, you'll authenticate the user using Passport.

To use Passport, you need to install both `passport` and `passport-local`.
```bash
npm install passport --save
npm install passport-local --save
``` 
You'll be using the `passport-local` strategy to authenticate the user login using a username and password.

Require both `passport` and `passport-local` in `app.js`.
```javascript
const  passport  =  require('passport');
const  LocalStrategy  =  require('passport-local').Strategy;
```
Passport has a number of [strategies](http://www.passportjs.org/) when it comes to authentication. You'll be using the local strategy in this tutorial and so we need to define it as below.
```javascript
passport.use(new LocalStrategy(
    function(username, password, done) {
        if(username === "admin" && password === "admin"){
            return done(null, username);
        } else {
            return done("unauthorized access", false);
        }
    }
));
```
The local strategy uses the username and password for authentication. For the sake of this tutorial, we have hardcoded the username and password check.

Before getting into the detailed code, let's have a look at how the Passport authentication executes.

- A request is received at the authenticate route.
- The custom middleware intercepts the request and makes the Passport authentication call.
- On successful authentication, Passport stores the user data in the session.
- On subsequent requests, Passport fetches the user data from the session for authentication.

 Let's make the Passport authentication call inside the custom middleware `auth`.
```javascript
const auth = () => {
    return (req, res, next) => {
        passport.authenticate('local', (error, user, info) => {
            if(error) res.status(400).json({"statusCode" : 200 ,"message" : error});
            req.login(user, function(error) {
                if (error) return next(error);
                next();
            });
        })(req, res, next);
    }
}
```
`passport.authenticate` invokes the `passport-local` strategy and, once authentication is done, the callback is invoked.

On successful authentication, Passport saves the user data in the session. For that to happen, you need to invoke `req.login` with the user object.

You also need to define the `serialize` and `deserialize` method to facilitate user data storage in the session and retrieving the data on subsequent requests.

```javascript
passport.serializeUser(function(user, done) {
    if(user) done(null, user);
});
  
passport.deserializeUser(function(id, done) {
    done(null, id);
});
```
Let’s now install and use the `body-parser` middleware so that the app can parse the posted parameters.
```bash
npm install body-parser --save
```
To use Passport, you need to initialize it and use it as below.
```javascript
app.use(passport.initialize());
app.use(passport.session());
```
To authenticate subsequent requests, you can define another middleware function. This function checks if the user data exists in the request. `passport` provides a method called `req.isAuthenticaed` which can be used to check if the user is authenticated.

Here is how the middleware function looks:
```javascript
const isLoggedIn = (req, res, next) => {
    if(req.isAuthenticated()){
        return next()
    }
    return res.status(400).json({"statusCode" : 400, "message" : "not authenticated"})
}
```
You can use the above middleware on other routes as shown below:
```javascript
app.get('/getData', isLoggedIn, (req, res) => {
    res.json("data")
})
```
Let's move on to adding the authentication to the Angular Dashboard app.

## Authenticating the Angular App

To add authentication to the Angular dashboard app, you need to add routes to the Angular application. From the project directory, execute the following command:
```bash
ng generate module app-routing --flat --module=app
```
It should create the routing module. Open `app-module.routing.ts` and replace it with the following code:
```javascript
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';

const routes: Routes = [
  { path: 'home', component: AppComponent },
  { path: 'login', component : LoginComponent}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
```
You'll be using two additional components in the Angular app called the `login` and `root` component. The `LoginComponent` will handle the login functionality and `RootComponent` will serve as the container for rendering different views.

```bash
ng generate component login
ng generate component root
```

### Adding Route Guard To The Home Route

To authenticate the Angular route from any unauthorized access, you'll be adding a route guard. The guard uses an authorization service to check if the route access is authenticated. 
Let's create an authorization service to check is access is authenticated.

```bash
ng generate service auth
```

The above command creates a service called `auth.service.ts`. Add the following code to it:

```javascript
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';


@Injectable({
  providedIn: 'root'
})
export class AuthService {

  constructor(private http : HttpClient) { }

  public isAuthenticated() : Boolean {
    let userData = localStorage.getItem('userInfo')
    if(userData && JSON.parse(userData)){
      return true;
    }
    return false;
  }

  public setUserInfo(user){
    localStorage.setItem('userInfo', JSON.stringify(user));
  }

  public validate(email, password) {
    return this.http.post('/api/authenticate', {'username' : email, 'password' : password}).toPromise()
  }
}
```
After validating the user login, `AuthService` saves the user information. It exposes a method called `isAuthenticated` which can be utilized by the `AuthGuardService` service to authenticate the route.

Let's create `AuthGuardService`.
```bash
ng generate service authGuard
```
Add the following code to the `auth-guard.service.ts` file.
```javascript
import { Injectable } from '@angular/core';
import { CanActivate,Router } from '@angular/router';
import {AuthService} from './auth.service';

@Injectable({
  providedIn: 'root'
})
export class AuthGuardService implements CanActivate {

  constructor(private authService : AuthService, private route : Router) { }

  canActivate(){
    if(this.authService.isAuthenticated()){
      return true;
    }
    this.route.navigate(['login']);
    return false;
  }
}	
```
The above `AuthGuardService` implements the `CanActivate` route guard. It means that, if the guard returns `true`, the navigation will continue; otherwise, it navigates to `login`.

Import `AuthGuardService` in `app-routing.module.ts`.
```javascript
import { 
  AuthGuardService as AuthGuard 
} from './auth-guard.service';
```
Add the route guard to the `home` route in `app-routing.module.ts`.

```javascript
const routes: Routes = [
  { path: 'home', component: AppComponent, canActivate : [AuthGuard] },
  { path: 'login', component : LoginComponent}
];
``` 
Inside the Login component, on click you need to make the API call the Node authentication API. Here is how the `login.component.ts` file looks:
```javascript
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../auth.service';
import { Router } from '@angular/router';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {

  userEmail : String;
  userPassword : String;

  constructor(private authService : AuthService, private router : Router) { }

  ngOnInit() {

  }

  login(){
    this.authService.validate(this.userEmail, this.userPassword)
    .then((response) => {
      this.authService.setUserInfo({'user' : response['user']});
      this.router.navigate(['home']);

    })
  }

}
```
For the API call to work from Angular to Node, you need to add a proxy `conf` file in the Angular app. Create a file called `proxy.conf.json` and add the following code :
```json
{
    "/api/*": {
      "target": "http://localhost:3000",
      "pathRewrite": {"^/api" : ""}
    }
  }
```
Save the above changes and run the Angular app along with the Node REST API. Open the `localhost:4200/home` route and you will be redirected to the login screen. Once there, enter the credentials as `admin` and `admin` and you will be redirected to the Angular dashboard screen.

## Wrapping it Up
In this tutorial, you learned how to authenticate a REST API using Passport. You also learned how to authenticate the Angular routes using route guards.

You used the `passport-local` strategy to implement authentication. In addition to `passport-local`, there are a number of [other Passport strategies](http://www.passportjs.org/) for authentication.

**Finally, don't forget to pay special attention if you're developing commercial Angular apps that contain sensitive logic. You can protect them against code theft, tampering, and reverse engineering by following <a href="https://blog.jscrambler.com/how-to-protect-angular-code-against-theft-and-reverse-engineering/?utm_source=dev.to&utm_medium=referral" target="_blank">our guide</a>**.