从 Angular 的第一个选项卡注销时,从第二个选项卡注销问题

sim*_*ser 4 authentication session-storage access-token angular

我正在使用 sessionStorage 来保存 accessToken。我的步骤如下:-

  • 登录网站
  • 单击选项卡的重复选项。它将在第二个选项卡中显示网站。
  • 从第一个选项卡注销。
  • 当我刷新/点击第二个选项卡上的任何操作时,希望从另一个选项卡注销。

实际上,它并没有将我从另一个选项卡中注销。

我添加了下面的代码,但它没有按预期工作。

@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']);
      }
    }
Run Code Online (Sandbox Code Playgroud)

如果我做错了什么,请告诉我。我目前在主页中使用此代码。它是正确的位置吗?

Dav*_*vid 5

要在选项卡之间进行通信,您可以使用localStorage并继续sessionStorage存储您的敏感数据。

这是一个身份验证服务的小实现,它使用:

  • sessionStorage 存储您的用户数据(令牌或其他)
  • localStorage 与其他打开的选项卡进行通信。
  • rxjs 从服务触发事件

这个想法是您的应用程序侦听存储事件。然后,当您退出时,它会在 中设置一个标志localStorage,其他打开的选项卡可以捕获该标志。

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

您可以在组件中使用该服务

constructor(private authSvc:AuthenticationService)
{
    this.authSvc.statusChanged$.subscribe(isLoggedIn=>
    {
      //Do whatever you want

    });
}
Run Code Online (Sandbox Code Playgroud)

这是一个stackblitz 演示