How to redirect to logout when token expired in angular 4

26,288

Solution 1

You can use Http Interceptors. If any Unauthorized 401 response. Suppose you are sending a http request with token in header. your server side code check your token and finally find out, token is invalid/expire return 401 code and you can redirect the user to login page. and manually passing token and checking all http request authorized/unauthorized is very repeated work, this common task you can do by interceptors as delegate for http request. see the code samples you'll get your solution.

AppHttpInterceptor.ts

import { Injectable } from "@angular/core";
import {
    HttpInterceptor,
    HttpRequest,
    HttpResponse,
    HttpErrorResponse,
    HttpHandler,
    HttpEvent
} from '@angular/common/http';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import { Http, Response, RequestOptions, Headers } from '@angular/http';
import { Router } from '@angular/router'


@Injectable()
export class AppHttpInterceptor implements HttpInterceptor {
    constructor(private router: Router){

    }
    headers = new Headers({
        'Content-Type': 'application/json',
        'Token': localStorage.getItem("Token")
    });
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        console.log("intercepted request ... ");

        // Clone the request to add the new header.
        const authReq = req.clone({ headers: req.headers.set("Token", localStorage.getItem("Token")) });

        console.log("Sending request with new header now ...");

        //send the newly created request
        return next.handle(authReq)
            .catch(err => {
                // onError
                console.log(err);
                if (err instanceof HttpErrorResponse) {
                    console.log(err.status);
                    console.log(err.statusText);
                    if (err.status === 401) {
                        window.location.href = "/login";
                    }
                }
                return Observable.throw(err);
            }) as any;
    }
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';
import { HttpClient } from "@angular/common/http";
import { FormsModule } from '@angular/forms';
import { ToasterModule, ToasterService } from "angular2-toaster";
import { BrowserAnimationsModule } from '@angular/platform-browser /animations';
import { RouterModule } from '@angular/router';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule,HTTP_INTERCEPTORS} from '@angular/common/http';
import {AppHttpInterceptor} from './Common/AuthInterceptor';
import { AppRoutes } from '../app/Common/Routes';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule, HttpModule,HttpClientModule, ReactiveFormsModule, FormsModule, BrowserAnimationsModule, RouterModule.forRoot(AppRoutes)
  ],
 providers: [
 {
   provide: HTTP_INTERCEPTORS,
   useClass: AppHttpInterceptor,
   multi: true
 }
],
bootstrap: [AppComponent]
})
export class AppModule { 
  constructor(private httpClient: HttpClient){
    this.httpClient.get("https://jsonplaceholder.typicode.com/users").subscribe(
  success => {
    console.log("Successfully Completed");
    console.log(success);
  }
  );
 }

}

Solution 2

you can check if the token is expired or not and as a response, you can redirect to login page store token in local storage for example

 yourmthod(parametr) {
        this.token = localStorage.getItem("token");
        this.headers = new Headers();
        this.headers.delete(this.token);
        this.headers.append("Authorization", this.token);
        return this._http.post(Constants.SERVER_URL + 'your method', {headers: this.headers});
    }

so it will response 401 error and you can handle this by redirecting to your login page

if any query you can ask a question in comments so I can help you

and you can also use if-else in your method

and you can write code in app.component.ts in onIt() method

ngOnInit(): void {
        let token = localStorage.getItem("token");
        if (token) {
            this.isTokenAvaialable = true;
            this.http.get(Constants.SERVER_URL + 'your mthod to validate token' + token).subscribe(data => {
                if (data == true) {
                    if (window.location.pathname == "") {
                        this.router.navigate(['/home', {outlets: {'r2': ['dashboard']}}]);
                    }
                } else if (data == false) {

                    this.logout('Server restarted.Please login again!!');
                } else {

                    this.logout('Session expired.Please login again.!!');
                }

            }, (err: HttpErrorResponse) => {
                this.toastr.warning('Server restarted.Please login again!!', 'Alert');
                localStorage.removeItem("token");
                this.isTokenAvaialable = false;
                this.logout('Server restarted.Please login again!!');
            });
        } else {
            this.isTokenAvaialable = false;
            this.router.navigate(['']);
            localStorage.removeItem("token");
            this.isTokenAvaialable = false;
        }
    }
Share:
26,288
pavithra rox
Author by

pavithra rox

A Software engineer that interested in javascript,cloud computing, NLP and machine lerning

Updated on July 16, 2022

Comments

  • pavithra rox
    pavithra rox almost 2 years

    I have a angular 4 application. There i use JWT token for authentication purposes. Everything works fine. but the token expiration time i have given to the JWT token is 1 hour. i want to log the user out from the front end application once the token expired on the server-side. in node backend, i use express middleware to handle this by checking if all the requests contain a valid token. Is there a way to do this angular side as well?

  • pavithra rox
    pavithra rox about 6 years
    this does nothing for me. i think this is not getting triggered. are you sure this sample code is right. do i have to do something more ?
  • chandrakant
    chandrakant about 6 years
    also you can use HttpIntercepter ,belo snippetCode import {Injectable} from '@angular/core'; import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http'; import {Observable} from 'rxjs/Rx'; @Injectable() export class deckAuthInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { let token = localStorage.getItem("token"); const authReq = req.clone({ headers: req.headers.set('Authorization', token) }); return next.handle(authReq); } }
  • sebu
    sebu about 6 years
    i have implemented in my project, its working fine. suppose you have 200+ apis for your project. those are the apis separated with multiple classes and methods. how you'll identify any request valid or not? by ngOnInit() you can check it, but its only for component loading time, what about after sending any post request.
  • sebu
    sebu about 6 years
    how can you detect the http request valid or not? suppose i want to save a customer, after sending the request , server gave me 401 error, how you'll notify the user your request is invalid. yes you can do it by error response in all method, but remember this common work you need to implement to your all action, which is overwhelming, interceptor'll allow you to do this common task. please read http interceptors in angular4
  • sebu
    sebu about 6 years
    one thing is important interceptors trigger only with HttpClient not Http
  • sebu
    sebu about 6 years
    check my app.module.ts constructor and with a http request calling, then you understand its work / not.
  • Muhammad Awais
    Muhammad Awais about 3 years
    Property 'catch' does not exist on type 'Observable<HttpEvent<any>>'. I am facing this error