Login and Authentication With Angular 6

Login and Authentication With Angular 6

Every application need some some sort of authentication. In this tutorial we are going to create a simple login page. If the login is successful, the user could see home page, Login and Authentication With Angular 6

Every application need some some sort of authentication. In this tutorial we are going to create a simple login page. If the login is successful, the user could see home page. If the login is not successful, then you would stay in login page. This tutorial is for understanding what we need to consider and it is the simplest way. You need to do more than this in production environment.

There is three aspect in each login:

1- Getting Token from server and storing it.

2- Use the stored token in order to access restricted APIs.

3- Guard restricted pages

Getting token from server and storing it

This step is very simple. All you have to do is to create a form, send the data to server, get the token and storing it. We use localstorage for storing our token.

First we need to create an authentication service.

ng generate service auth

And you change the authService file like this:

import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {Observable, of} from 'rxjs';
import {catchError, tap} from 'rxjs/internal/operators';
const httpOptions = {
    headers: new HttpHeaders({'Content-Type': 'application/json'})
};
@Injectable({
    providedIn: 'root'
})
export class AuthService {
    private url = '/login/';
    constructor(private http: HttpClient) {
    }
    login(data): Observable<any> {
        return this.http.post<any>(this.url, data, httpOptions).pipe(
            tap((result) => this.save_token(result)),
            catchError(this.handleError<any>('login'))
        );
    }
    private handleError<T>(operation = 'operation', result?: T) {
        return (error: any): Observable<T> => {
            return of(result as T);
        };
    }
    private save_token(data) {
        if (data.success) {
            localStorage.setItem('token', data.token);
            return;
        }
    }
}

We have a constructor and three function in this service. The constructor is responsible to initiate the httpClient. In login method, we create a post request with the data that is provided by our component. We then send this request to the server (with /login url) and get the response. Login method needs to return an observable. We use pipe and tap in order to achieve this.

Pipe is set to chain some operations and return an observable that is result of all the operations. The tap method is responsible to perform an action on the result and returns an observable that is identical to the source. We use tap to save the token.

In save_token function if the result of login is successful, then we save the token in to the localStorage. After that the tap method sends returns the result observable. The catchError method is responsible to handle error. Our handleError does pretty much nothing.

Then we create a login component. In this component we create a form that gets the data from user and send it to the service

ng generate component login

And the component should look like this:

import {Component, OnInit} from '@angular/core';
import {NgForm} from '@angular/forms';
import {Router} from '@angular/router';
import {AuthService} from '../auth.service';

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

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

    data = {username: '', password: ''};

    ngOnInit() {
    }

    goTo(path): void {
        this.router.navigateByUrl(path);
    }

    login(form: NgForm): void {
        this.authService.login(form.value)
            .subscribe(result => {
                if (result.success) {
                    this.goTo('home');
                }
            });
    }

}

The login function gets the form info and send it to authService (which is initiated in constructor). If the result is successful to goTo function redirects to home page.

Using the stored token in order to access restricted APIs

Now we have a token saved in our token in our localstorage, we need to use this token in order to access restricted APIs. To do so we can create an http interceptor. By default your application uses default angular http interceptor. In order to change that, we need to go to app.module.ts file and change this part:

providers: [
    {
        provide: ErrorHandler,
        useClass: CustomErrorsHandler
    },
    {
        provide: HTTP_INTERCEPTORS,
        useClass: CustomHttpInterceptor, // change this line with your custom http interceptor
        multi: true
    }
],

Then create a file named custom-http-interceptor.ts and fill it as follow:

import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Router } from '@angular/router';

@Injectable()
export class CustomHttpInterceptor implements HttpInterceptor {
    constructor(private router: Router) { }
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    

        let obj = JSON.parse(localStorage.getItem('token')

        if (obj != null) {
            req = req.clone({
                setHeaders: { 'Authorization': obj.value }
            });
        }
        else {
            if (req.url != 'login') {
                this.router.navigate(['login']);
                return;
            }
        }
        return next.handle(req);
    }
}

In this file we create a class named CustomHttpInterceptor and we override function intercept. First we check if there is any token saved in localstorage. if there is, we send this token with url with appropriate header (In this case ‘Authorization’), if it is not, we check if the requested url needs token or not. if it doesn’t we send the request with no token.

Guard restricted pages

So far we have saved our token in localstorage and we also managed to send this token with every request. Now we need to limit users to access specific pages if they are not allowed. To do that we can use in canActivate our routing file. First we add canActivate method to our authService.

canActivate(): boolean {
const token = localStorage.getItem('token');
    if (token == null)   {
        this.router.navigate(['login']);
        return false;
    }
    return true;
}

In this method we check if the token is available or not. If so, we return true otherwise we return false.

Then in our routing module (app.routing.module.ts) we change routes as follow:

const routes: Routes = [
    {path: '', redirectTo: '/login', pathMatch: 'full'},
    {
        path: 'home', component: HomeComponent,
        canActivate: [AuthService] // <- this line is added
    },
    {path: 'login', component: LoginComponent},
];

With canActivate property, we check whether the home component is accessible by user or not.

Conclusion

This tutorial is extremely simplified and its only purpose is for you to see all the aspects in one place. It is not suitable for the production environment. Security concerns such as plain text passwords are not considered. You can do a lot of things to improve it. For example you can use angular-jwtin order to check token’s validity. Regardless of that I believe a simple big picture on what needs to be done and in what place it should be is important. Hope this would help you.

Angular 6 (formerly Angular 2) - The Complete Guide

Learn Angular 2 from Beginner to Advanced

Angular 2 Firebase - Build a Web App with Typescript

Angular 2 Demystified

What are the best alternatives for angular js?

<img src="https://moriohcdn.b-cdn.net/193902114c.png">There are numerous frameworks and libraries used across the globe. If not angular, there are platforms like React, Vue, Aurelia and so on for app development.

There are numerous frameworks and libraries used across the globe. If not angular, there are platforms like React, Vue, Aurelia and so on for app development.

Angular 8 Node & Express JS File Upload

Angular 8 Node & Express JS File Upload

In this Angular 8 and Node.js tutorial, we are going to look at how to upload files on the Node server. To create Angular image upload component, we will be using Angular 8 front-end framework along with ng2-file-upload NPM package; It’s an easy to use Angular directives for uploading the files.

In this Angular 8 and Node.js tutorial, we are going to look at how to upload files on the Node server. To create Angular image upload component, we will be using Angular 8 front-end framework along with ng2-file-upload NPM package; It’s an easy to use Angular directives for uploading the files.

We are also going to take the help of Node.js to create the backend server for Image or File uploading demo. Initially, we’ll set up an Angular 8 web app from scratch using Angular CLI. You must have Node.js and Angular CLI installed in your system.

We’ll create the local server using Node.js and multer middleware. Multer is a node.js middleware for handling multipart/form-data, which is primarily used for uploading files. Once we are done setting up front-end and backend for our File uploading demo then, we’ll understand step by step how to configure file uploading in Angular 8 app using Node server.

Prerequisite

In order to show you Angular 8 File upload demo, you must have Node.js and Angular CLI installed in your system. If not then check out this tutorial: Set up Node JS

Run following command to install Angular CLI:

npm install @angular/cli -g

Install Angular 8 App

Run command to install Angular 8 project:

ng new angular-node-file-upload

# ? Would you like to add Angular routing? No
# ? Which stylesheet format would you like to use? CSS
cd angular-node-file-upload

Show Alert Messages When File Uploaded

We are going to install and configure ngx-toastr an NPM package which helps in showing the alert message when the file is uploaded on the node server.

npm install ngx-toastr --save

The ngx-toastr NPM module requires @angular/animations dependency:

npm install @angular/animations --save

Then, add the ngx-toastr CSS in angular.json file:

"styles": [
    "src/styles.css",
    "node_modules/ngx-toastr/toastr.css"
]

Import BrowserAnimationsModule and ToastrModule in app.module.ts file:

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ToastrModule } from 'ngx-toastr';
 
@NgModule({
  imports: [
    CommonModule,
    BrowserAnimationsModule, // required animations module
    ToastrModule.forRoot() // ToastrModule added
  ]
})

export class AppModule { }

Install & Configure ng-file-upload Directive

In this step, we’ll Install and configure ng-file-upload library in Angular 8 app. Run command to install ng-file-upload library.

npm install ng2-file-upload

Once the ng2-file-upload directive is installed, then import the FileSelectDirective and FormsModule in app.module.ts. We need FormsModule service so that we can create the file uploading component in Angular.

import { FileSelectDirective } from 'ng2-file-upload';
import { FormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    FileSelectDirective
  ],
  imports: [
    FormsModule
  ]
})

export class AppModule { }

Setting Up Node Backend for File Upload Demo

To upload the file on the server, we need to set up a separate backend. In this tutorial, we will be using Node & Express js to create server locally along with multer, express js, body-parser, and dotenv libraries.

Run command to create backend folder in Angular app’s root directory:

mkdir backend && cd backend

In the next step, create a specific package.json file.

npm init

Run command to install required dependencies:

npm install express cors body-parser multer dotenv --save

In order to get rid from starting the server again and again, install nodemon NPM package. Use –-save-dev along with the npm command to register in the devDependencies array. It will make it available for development purpose only.

npm install nodemon --save-dev

Have a look at final pacakge.json file for file upload demo backend:

{
  "name": "angular-node-file-upload",
  "version": "1.0.0",
  "description": "Angualr 8 file upload demo app",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node server.js"
  },
  "author": "Digamber Rawat",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.19.0",
    "cors": "^2.8.5",
    "dotenv": "^8.0.0",
    "express": "^4.17.1",
    "multer": "^1.4.1"
  },
  "devDependencies": {
    "nodemon": "^1.19.1"
  }
}

Create a file by the name of server.js inside backend folder:

Configure Server.js

To configure our backend we need to create a server.js file. In this file we’ll keep our backend server’s settings.

touch server.js

Now, paste the following code in backend > server.js file:

const express = require('express'),
  path = require('path'),
  cors = require('cors'),
  multer = require('multer'),
  bodyParser = require('body-parser');

// File upload settings  
const PATH = './uploads';

let storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, PATH);
  },
  filename: (req, file, cb) => {
    cb(null, file.fieldname + '-' + Date.now())
  }
});

let upload = multer({
  storage: storage
});

// Express settings
const app = express();
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: false
}));

app.get('/api', function (req, res) {
  res.end('File catcher');
});

// POST File
app.post('/api/upload', upload.single('image'), function (req, res) {
  if (!req.file) {
    console.log("No file is available!");
    return res.send({
      success: false
    });

  } else {
    console.log('File is available!');
    return res.send({
      success: true
    })
  }
});

// Create PORT
const PORT = process.env.PORT || 8080;
const server = app.listen(PORT, () => {
  console.log('Connected to port ' + PORT)
})

// Find 404 and hand over to error handler
app.use((req, res, next) => {
  next(createError(404));
});

// error handler
app.use(function (err, req, res, next) {
  console.error(err.message);
  if (!err.statusCode) err.statusCode = 500;
  res.status(err.statusCode).send(err.message);
});

Now, while staying in the backend folder run the below command to start the backend server:

nodemon server.js

If everything goes fine then you’ll get the following output:

[nodemon] 1.19.1
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node server.js`
Connected to port 8080

Create Angular 8 File Upload Component

In this last step, we are going to create a file upload component in Angular 8 app using Express js API.

Get into the app.component.ts file and include the following code:

import { Component, OnInit } from '@angular/core';
import { FileUploader } from 'ng2-file-upload/ng2-file-upload';
import { ToastrService } from 'ngx-toastr';

const URL = 'http://localhost:8080/api/upload';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit {
  public uploader: FileUploader = new FileUploader({
    url: URL,
    itemAlias: 'image'
  });

  constructor(private toastr: ToastrService) { }

  ngOnInit() {
    this.uploader.onAfterAddingFile = (file) => {
      file.withCredentials = false;
    };
    this.uploader.onCompleteItem = (item: any, status: any) => {
      console.log('Uploaded File Details:', item);
      this.toastr.success('File successfully uploaded!');
    };
  }

}

Go to app.component.html file and add the given below code:

<div class="wrapper">
  <h2>Angular Image Upload Demo</h2>

  <div class="file-upload">
    <input type="file" name="image" ng2FileSelect [uploader]="uploader" accept="image/x-png,image/gif,image/jpeg" />
    <button type="button" (click)="uploader.uploadAll()" [disabled]="!uploader.getNotUploadedItems().length">
      Upload
    </button>
  </div>

</div>

Now, It’s time to start the Angular 8 app to check out the File upload demo in the browser. Run the following command:

ng serve --open

Make sure your NODE server must be running to manage the backend.

When you upload the image from front-end you’ll see your image files are saving inside the backend > uploads folder.

Conclusion

In this Angular 8 tutorial, we barely scratched the surface related to file uploading in a Node application. There are various other methods available on the internet through which you can achieve file uploading task quickly. However, this tutorial is suitable for beginners developers. I hope this tutorial will surely help and you if you liked this tutorial, please consider sharing it with others.

Angular JS Development Company

If you’re finding AngularJS Development Company for consultation or Development, your search ends here at Data EximIT 

🔗 Click here to know more: AngularJS Development