Introduction
In this posting, we will build a simple login system complete with user authentication with JSON Web Token (JWT) using Angular and Express. Let’s get started!
Installation & Setup
First of all, make sure you have already installed NodeJs on your machine. After that, run the following command in your command line to install angular/cli and then create a new Angular app. You can name your Angular app whatever name you like.
npm install -g @angular/cli
mkdir simple-angular
ng new my-simple-angular
cd my-simple-angular
ng serve
This will start your Angular app on port 4200.
Open another command line and run the following command to create the backend app with Express. Create a folder and make sure on the same level of my-simple-angular
folder
mkdir back-end cd back-end npm init
It will ask for several inputs, input the name and leave the rest empty, answer Yes at the end.
This will create the package.json
file. Now we are going to get the packages that we need for this project.
npm install express --save npm install nodemon npm install cors npm install mysql npm install jsonwebtoken npm install util
Now, create a file and name it app.js
. This file will be our main file for now. Go to your package.json
and under scripts
, add like so.
{
"name": "simple-angular",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start" : "nodemon app.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.1",
"nodemon": "^2.0.3"
}
}
The only extra thing I add here is the “start” under “scripts”.
In your app.js file, copy and paste the following.
const express = require('express');
const app = express();
app.listen(4000, () => {
console.log('listening on port 4000');
})
Run npm start
. Great. Now, we have setup both Angular App and Express backend. Time to build all the front-end stuff on our Angular app like the login page, register page etc. Once that is done, we will build a REST API endpoint on our backend to handle our login/register logic and return a JSON Web Token (JWT).
Open your command line and go to your app folder in your Angular app. Run the following commands to create an Auth Module
.
ng g module auth/auth
Now, you have another module called AuthModule, make sure to import this module in your app.module.ts
@NgModule({ declarations: [ AppComponent, ], imports: [ BrowserModule, AppRoutingModule. AuthModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Now, time to create a couple of components in our Auth folder.
ng g component auth/components/login
ng g component auth/components/register
These will create two components and will be imported in the AuthModule. Check if you have this correctly.
@NgModule({ declarations: [ LoginComponent, RegisterComponent ], imports: [ CommonModule ], exports : [ LoginComponent, RegisterComponent ] }) export class AuthModule { }
Open you app-routing.module and replace the Routes with the following.
const routes: Routes = [ {path: 'login', component: LoginComponent}, {path: 'register', component: RegisterComponent}, ];
Adding Bootstrap 4 to our Angular app
Now your components are connected, we now have to construct the HTML for our navbar so we can navigate between these two pages. We are going to add Bootstrap 4 to our Angular app. Run the following code.
npm install --save bootstrap npm install --save jquery
Open the angular.json
file of your project and include:
node_modules/bootstrap/dist/css/bootstrap.css
in the projects->architect->build->styles
array,
node_modules/bootstrap/dist/js/bootstrap.js
in the projects->architect->build->scripts
array,
node_modules/bootstrap/dist/js/bootstrap.js
in the projects->architect->build->scripts
array

Now go back to your app.component.html and replace with the following.
<nav class="navbar navbar-expand-lg navbar-light bg-light"> <a class="navbar-brand" href="#">Navbar</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarNav"> <ul class="navbar-nav"> <li class="nav-item active"> <a class="nav-link" [routerLink] = "['']" routerLinkActive = "active">Home</a> </li> <li class="nav-item"> <a class="nav-link" [routerLink] = "['login']" routerLinkActive = "active">Login</a> </li> <li class="nav-item"> <a class="nav-link" [routerLink] = "['register']" routerLinkActive = "active" >Register</a> </li> </ul> </div> </nav> <router-outlet></router-outlet>
In your app.module.ts. Add the following. Your module should looks like this.
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { RouterModule} from '@angular/router'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { AuthModule } from './auth/auth/auth.module'; @NgModule({ declarations: [ AppComponent, ], imports: [ BrowserModule, AppRoutingModule, RouterModule, AuthModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Run your angular app and you should have something like this. A navbar where you can navigate between login and navigate.

Creating Services
Now, before we construct the HTML for our login and register page. We are going to create 2 service files. One for the HTTP request and another one for localStorage handler. Run the below command to create 2 service files.
ng g service services/auth ng g service services/api
Open your api.service.ts
file and paste the following code.
import { Injectable } from '@angular/core'; import { environment } from '../../environments/environment'; import { HttpClient } from '@angular/common/http'; import { map } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class ApiService { baseUrl = 'http://localhost:4000/'; constructor(private _http: HttpClient) { } getTypeRequest(url) { return this._http.get(`${this.baseUrl}${url}`).pipe(map(res => { return res; })); } postTypeRequest(url, payload) { return this._http.post(`${this.baseUrl}${url}`, payload).pipe(map(res => { return res; })); } putTypeRequest(url, payload) { return this._http.put(`${this.baseUrl}${url}`, payload).pipe(map(res => { return res; })); } }
For you auth.service.ts
.
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class AuthService { constructor() { } getUserDetails() { return localStorage.getItem('userData') ? JSON.parse(localStorage.getItem('userData')) : null; } setDataInLocalStorage(variableName, data) { localStorage.setItem(variableName, data); } getToken() { return localStorage.getItem('token'); } clearStorage() { localStorage.clear(); } }
Now we have 2 services that we can use an injectable in any components in the App. The first service is the api.service which we will use to make an API call to our backend and the second one is for authentication purpose when user logs in.
Constructing the HTML for Login and Register pages
Open up your login.component.html
and paste the following.
<div class = 'row m-0 w-100'> <div class = 'col-md-4 offset-4 mt-5' *ngIf = '!this.isLogin'> <h4>Login</h4> <form #myform = "ngForm" (ngSubmit) = "onSubmit(myform)" > <div class = 'form-group'> <input class = 'form-control' type = "text" name = "username" placeholder = "Username" ngModel> </div> <div class = 'form-group'> <input class = 'form-control' type = "password" name = "password" placeholder = "Password" ngModel> </div> <input class= 'btn btn-outline-info' type = "submit" value = "Login"> </form> </div> <div class = 'col-md-4 offset-4 mt-5' *ngIf = 'this.isLogin'> <h1>You are logged in</h1> <button class = 'btn btn-outline-info' (click) = 'logout()'>Log-out</button> </div> </div>
Open your login.component.ts
import { Component, OnInit } from '@angular/core'; import {NgForm} from '@angular/forms'; import { ApiService } from './../../../services/api.service' import { AuthService } from './../../../services/auth.service' import { Router } from '@angular/router'; @Component({ selector: 'app-login', templateUrl: './login.component.html', styleUrls: ['./login.component.css'] }) export class LoginComponent implements OnInit { isLogin: boolean = false errorMessage constructor( private _api: ApiService, private _auth: AuthService, private _router:Router ) { } ngOnInit() { this.isUserLogin(); } onSubmit(form: NgForm) { console.log('Your form data : ', form.value); this._api.postTypeRequest('user/login', form.value).subscribe((res: any) => { if (res.status) { console.log(res) this._auth.setDataInLocalStorage('userData', JSON.stringify(res.data)); this._auth.setDataInLocalStorage('token', res.token); this._router.navigate(['']); } else { } }, err => { this.errorMessage = err['error'].message; }); } isUserLogin(){ console.log(this._auth.getUserDetails()) if(this._auth.getUserDetails() != null){ this.isLogin = true; } } logout(){ this._auth.clearStorage() this._router.navigate(['']); } }
Now, open your register.component.html
. Copy and paste the following. Followed by register.component.ts
<div class = 'row m-0 w-100'> <div class = 'col-md-4 offset-4 mt-5' *ngIf = '!this.isLogin'> <h4>Register</h4> <form #myform = "ngForm" (ngSubmit) = "onSubmit(myform)" > <div class = 'form-group'> <input class = 'form-control' type = "text" name = "username" placeholder = "Username" ngModel> </div> <div class = 'form-group'> <input class = 'form-control' type = "email" name = "email" placeholder = "Email" ngModel> </div> <div class = 'form-group'> <input class = 'form-control' type = "password" name = "password" placeholder = "Password" ngModel> </div> <input class= 'btn btn-outline-info' type = "submit" value = "Register"> </form> </div> <div class = 'col-md-4 offset-4 mt-5' *ngIf = 'this.isLogin'> <h5>You are logged in</h5> </div> </div>
import { Component, OnInit } from '@angular/core'; import { ApiService } from './../../../services/api.service' import { AuthService } from './../../../services/auth.service' import {NgForm} from '@angular/forms'; import { Router } from '@angular/router'; @Component({ selector: 'app-register', templateUrl: './register.component.html', styleUrls: ['./register.component.css'] }) export class RegisterComponent implements OnInit { isLogin: boolean = false errorMessage constructor( private _api: ApiService, private _auth: AuthService, private _router:Router ) { } ngOnInit() { this.isUserLogin(); } onSubmit(form: NgForm) { console.log('Your form data : ', form.value); this._api.postTypeRequest('user/register', form.value).subscribe((res: any) => { if (res.status) { console.log(res) this._auth.setDataInLocalStorage('userData', JSON.stringify(res.data)); this._auth.setDataInLocalStorage('token', res.token); this._router.navigate(['login']); } else { console.log(res) alert(res.msg) } }, err => { this.errorMessage = err['error'].message; }); } isUserLogin(){ if(this._auth.getUserDetails() != null){ this.isLogin = true; } } }
Now, in the login
and register
component. What we are doing is we constructed a login/register box to allow user to input username and password. Onsubmit
, we are making an API call to the back-end and on success response, we set a localStorage
for the userData
and the token
.
Also, here is the final content of your app.module.ts
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { RouterModule} from '@angular/router'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { AuthModule } from './auth/auth/auth.module'; import { FormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; @NgModule({ declarations: [ AppComponent, ], imports: [ BrowserModule, AppRoutingModule, RouterModule, AuthModule, FormsModule, HttpClientModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Followed by auth.module.ts
.
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { LoginComponent } from '../components/login/login.component'; import { RegisterComponent } from '../components/register/register.component'; import { FormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; @NgModule({ declarations: [ LoginComponent, RegisterComponent ], imports: [ CommonModule, FormsModule, HttpClientModule ], exports : [ LoginComponent, RegisterComponent ] }) export class AuthModule { }
Back-end Setup (Express)
Now, it’s time to setup our back-end to handle our login and register logic. For database, we are going to use MySQL, so go ahead and create a table in your database called user.
CREATE TABLE `users` ( `id` int(11) NOT NULL, `username` varchar(255) NOT NULL, `email` varchar(255) NOT NULL, `password` varchar(255) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Then, create another folder, name it routes
and inside the routes folder create two files, name it as index.js
and user.js
like so.

Open your index.js
and paste the following
var express = require('express'); var router = express.Router(); var user = require('./user'); router.use('/user', user); module.exports = router;
Next, copy and paste the following into your user.js
var express = require('express'); var router = express.Router(); var md5 = require('md5'); var jwt = require('jsonwebtoken'); var mysql = require('mysql'); var con = mysql.createConnection({ host: "localhost", user: "root", password: "", database: "simpleangular" }); /* GET users listing. */ router.post('/register', async function (req, res, next) { try { let { username, email, password } = req.body; const hashed_password = md5(password.toString()) const checkUsername = `Select username FROM users WHERE username = ?`; con.query(checkUsername, [username], (err, result, fields) => { if(!result.length){ const sql = `Insert Into users (username, email, password) VALUES ( ?, ?, ? )` con.query( sql, [username, email, hashed_password], (err, result, fields) =>{ if(err){ res.send({ status: 0, data: err }); }else{ let token = jwt.sign({ data: result }, 'secret') res.send({ status: 1, data: result, token : token }); } }) } }); } catch (error) { res.send({ status: 0, error: error }); } }); router.post('/login', async function (req, res, next) { try { let { username, password } = req.body; const hashed_password = md5(password.toString()) const sql = `SELECT * FROM users WHERE username = ? AND password = ?` con.query( sql, [username, hashed_password], function(err, result, fields){ if(err){ res.send({ status: 0, data: err }); }else{ let token = jwt.sign({ data: result }, 'secret') res.send({ status: 1, data: result, token: token }); } }) } catch (error) { res.send({ status: 0, error: error }); } }); module.exports = router;
Finally, in your app.js
, paste the following.
const express = require('express'); var indexRouter = require('./routes/index'); var cors = require('cors'); const app = express(); app.use(cors()) app.use(express.json()); app.use('/', indexRouter); app.listen(4000, () => { console.log('listening on port 4000'); })
There, we have set up our API endpoint on our Express. Start both of your apps now, Angular and Express. That is it for our tutorial. See you on the next tutorial. Stay tuned!