'Call method on close of browser not refresh
I am creating a project using angular, in my application i want to logout the user when user closes the browser, but the problem is user also logged out when page refreshes. I want to stop this on page refresh.
@HostListener('window:beforeunload', ['$event'])
onBeforeUnload(): void {
navigator.sendBeacon('logout');
}
I tried a lot in google but didn't find any solution to achieve this. If it is not possible in angular, can please guide me how we can achieve this.
Solution 1:[1]
I would store a timestamp on on localStroage to keep user's logged in status (ideally this could be refactored to your authentication service and using AuthGuards.
When user logs in we post a token to storage. After refresh, or any other type of load, we try to read the token from storage. Also with beforeunload we update the token one last time before the window closes.
On opening the page we check if we have a token in storage and we check that it's not older than 5 seconds. If the token is newer than 5 seconds user is logged in.
This means that refresh which happens faster than 5 seconds user remains logged in. And we assume that closing the browser takes more than 5 seconds. We can't really use window:beforeunload solely because like others pointed out - to the browser, it's the same when refreshing, when closing the tab, or closing the browser itself.
This simplified example is common case for keeping frontend user's session alive with tokens in storage which in one form or the other check validity of the session (in this case it's time based). Though in reality handling the tokens should be more secure and usually backend will keep the session itself alive and frontend will just read to token value, validate and log user in and update the token it if necessary.
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
isLoggedIn = false;
token: string;
now = new Date();
@HostListener('window:beforeunload', ['$event'])
onBeforeUnload(): void {
if (this.isLoggedIn) {
localStorage.setItem('myToken', this.now.toISOString());
console.log('beforeunload:', localStorage.getItem('myToken'));
}
navigator.sendBeacon('logout');
}
constructor() {}
ngOnInit() {
this.checkIsLoggedIn();
}
// user will remain logged in for 5 seconds
checkIsLoggedIn() {
this.token = localStorage.getItem('myToken');
if (this.token) {
const currentTime = this.now.getTime() - 5 * 1000;
const previousTime = new Date(this.token).getTime();
if (currentTime < previousTime) {
console.log('prev: ', previousTime);
console.log('curr: ', currentTime);
this.isLoggedIn = true;
}
}
}
onLogin() {
localStorage.setItem('myToken', this.now.toISOString());
this.token = localStorage.getItem('myToken');
if (this.token) {
this.isLoggedIn = true;
}
console.log(this.token);
}
}
Working example: https://stackblitz.com/edit/angular-ivy-ff9jns?file=src%2Fapp%2Fapp.component.ts
Solution 2:[2]
You can try something like this.
@HostListener('window:beforeunload', ['$event'])
onBeforeUnload(): void {
if ((window.event.clientY < 0)) {
// your logout logic
}
};
Solution 3:[3]
You can use local storage for saving the auth token and fetch after refreshing the browser. Or you can use NgRx state management for that.
Solution 4:[4]
I don't have any experience with angular, but I know about sessionStorage. Basically, it will perish after the tab is closed but it will persist after page refreshes. Here's the MDN, it contains the exact details.
Solution 5:[5]
Just save the login keys on window.sessionStorage then when the user close the page the data will disappear. but it stays on refresh
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | s.stkvc |
| Solution 3 | Master |
| Solution 4 | mollthecoder |
| Solution 5 | pery mimon |
