I am using sessionStorage to hold accessToken. My steps are as follows:-
Actually it is not logging me out from another tab.
I added below code but it is not working as expected.
@HostListener('window:storage', ['$event'])
onStorageChange(sv:StorageEvent) {
if(sv.storageArea == sessionStorage)
{
let token = sessionStorage.getItem('accessToken');
if(token == null || token == undefined)
this.router.navigate(['/login']);
}
}
Please let me know if I am doing any mistake. I am currently using this code in home page. Is it the right location?
To communicate between tabs, you can make use of localStorage
and still keep sessionStorage
to store your sensitive data.
Here is a small implementation of an authentication service which uses:
sessionStorage
to store your user data (token or whatever) localStorage
to communicate with other opened tabs.rxjs
to trigger events from the serviceThe idea is that your application listens for storage events. Then when you sign out, it sets a flag in localStorage
, which other opened tabs can capture.
import { Injectable } from "@angular/core";
import { Subject, Observable } from "rxjs";
@Injectable({providedIn:'root'})
export class AuthenticationService{
private eventSubject: Subject<boolean> = new Subject<boolean>();
public readonly statusChanged$: Observable<boolean> = this.eventSubject.asObservable();
private loggedIn = false;
constructor()
{
window.onstorage = () => { //
{
let loggedIn = sessionStorage.getItem('accessToken') !== null;
if(localStorage.getItem('signOut'))
{
loggedIn = false;
}
if(this.loggedIn !== loggedIn)//Don't trigger event if no change
{
this.loggedIn = loggedIn;
this.eventSubject.next(loggedIn);
}
};
}
}
public logIn()
{
//Do your business to login and obtain a token before here...
localStorage.removeItem('signOut');//clear flag in local storage
sessionStorage.setItem('accessToken', 'token');//save token in session storage
}
public logOut()
{
localStorage.setItem('signOut', 'true'); //trigger flag
sessionStorage.removeItem('accessToken'); //Remove token from session
}
public isLoggedIn()
{
return this.loggedIn;
}
}
You can just use that service in your components
constructor(private authSvc:AuthenticationService)
{
this.authSvc.statusChanged$.subscribe(isLoggedIn=>
{
//Do whatever you want
});
}
Here is a stackblitz demo.