Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I watch for changes to localStorage in Angular2?

I was trying to figure out how to get a menu to appear and disappear based on being logged in in a previous post. But I think a better and possibly easier question would be, how can I watch for changes to localstorage?

I am using json web tokens in local storage for my authentication, I would love to watch for a change to localStorage and then re-update my view on new information.

I set my localStorage with this

localStorage.setItem('jwt', my_token); 

The things I would like to do is check if I have a token, if I don't nothing happens, but when there is a change fire an event. I would especially like it if I could only watch for a certain named event like localStorage.getItem('jwt').

Thanks!

EDIT:

Gunter pointed me in the right direction but just in case anyone is still fairly confused by that, here is a plunker showing you how to do it. http://plnkr.co/edit/TiUasGdutCsll1nI6USC?p=preview

like image 748
Morgan G Avatar asked Feb 14 '16 19:02

Morgan G


People also ask

Can clients modify localStorage?

You have all the code written to test it in your OP. You should assume that any data held on the client could be altered with the right amount of skills and knowledge. If security is an issue, you should not base your application security around presistent storage or persistent cookies for that matter.

Can localStorage be hacked?

On the downside, localStorage is potentially vulnerable to cross-site scripting (XSS) attacks. If an attacker can inject malicious JavaScript into a webpage, they can steal an access token in localStorage. Also, unlike cookies, localStorage doesn't provide secure attributes that you can set to block attacks.

Do tabs share localStorage?

The main features of localStorage are: Shared between all tabs and windows from the same origin. The data does not expire. It remains after the browser restart and even OS reboot.

How do I get data from local storage in Angular 8?

Save the Angular app and run the application. After the app gets loaded, type in localStorage from the browser console and you will be able to see the encrypted data in local storage. While trying to access the local storage data inside the application, you can get the decrypted data.


1 Answers

The key thing is to use window.addEventListener("storage", . While the library probably does it the "right" way for angular, here is a "light" version I put together, using .bind(this) instead of mucking about in angular's internals.

    import { Injectable, OnDestroy } from '@angular/core';     import { Subject } from 'rxjs/Subject';     import { share } from 'rxjs/operators';          @Injectable()     export class StorageService implements OnDestroy {       private onSubject = new Subject<{ key: string, value: any }>();       public changes = this.onSubject.asObservable().pipe(share());            constructor() {         this.start();       }            ngOnDestroy() {         this.stop();       }            public getStorage() {         let s = [];         for (let i = 0; i < localStorage.length; i++) {           s.push({             key: localStorage.key(i),             value: JSON.parse(localStorage.getItem(localStorage.key(i)))           });         }         return s;       }            public store(key: string, data: any): void {         localStorage.setItem(key, JSON.stringify(data));         this.onSubject.next({ key: key, value: data})       }            public clear(key) {         localStorage.removeItem(key);         this.onSubject.next({ key: key, value: null });       }                 private start(): void {         window.addEventListener("storage", this.storageEventListener.bind(this));       }            private storageEventListener(event: StorageEvent) {         if (event.storageArea == localStorage) {           let v;           try { v = JSON.parse(event.newValue); }           catch (e) { v = event.newValue; }           this.onSubject.next({ key: event.key, value: v });         }       }            private stop(): void {         window.removeEventListener("storage", this.storageEventListener.bind(this));         this.onSubject.complete();       }     } 

LocalStorageTwoTabs

like image 177
Stephen Avatar answered Oct 10 '22 21:10

Stephen