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?
For example, once an access token expires, the client application could prompt the user to log in again to get a new access token. Alternatively, the authorization server could issue a refresh token to the client application that lets it replace an expired access token with a new one.
The JWT access token is only valid for a finite period of time. Using an expired JWT will cause operations to fail.
You can use a lib(like jwt_decode) to decode your JWT token, where it's most likely contains an expiration timestamp that you can check(compare it with the current timestamp for this moment) and if it exceeded(expired) just delete it from local storage and redirect user to login page.
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);
}
);
}
}
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With