如何在SubjectBehavior之前检查Google扩展程序存储空间?

时间:2017-11-30 13:00:55

标签: javascript angular google-chrome-extension rxjs

我有一个身份验证警卫,可以检查来自BehaviorSubject的结果,但是在检查之前,我需要检查在回调中返回值的chrome本地存储,如果令牌无效,请更新它并通知{{ 1}}允许特定的路线。

如何查看BehaviorSubject功能中的本地存储空间?

按照代码更好地了解流程。

auth.guard.ts

get

auth.service.ts

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(
    private authService: AuthService,
    private router: Router
  ) {}

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> {
    return this.authService.isLoggedIn
      .take(1)
      .map((isLoggedIn: boolean) => {
        if (isLoggedIn) {
          return true;
        }

        this.router.navigate(['/login']);
        return false;
      });
  }
}

3 个答案:

答案 0 :(得分:1)

如果您正在做的就是这样,那么您就不需要使用可观察对象了。你不是在做任何异步的事情。您只想检查本地存储的当前值,以查看用户是否仍在进行身份验证。

CanActivate界面允许您返回Observable<boolean> | Promise<boolean> | boolean。所以你可以这样做:

<强> auth.guard.ts

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(
    private authService: AuthService,
    private router: Router
  ) {}

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> {
    if(this.authService.isLoggedIn) {
       return true;
    }
    this.router.navigate(['/login']);
    return false;
  }
}

<强> auth.service.ts

export class AuthService {
    get isLoggedIn() {
        return localStorage.getItem('my-auth-key');
    }
}

如果您需要在应用程序中出于其他原因将身份验证状态公开为可观察状态,则可以在将会话置于本地存储中时设置计时器。它可以在可接受的时间间隔内轮询,将其设置为会话的绝对到期时间,或类似的内容,具体取决于您的身份验证方案。基本概念是使您的本地存储成为可观察的唯一方法。是使用计时器或某些事件。

对于我工作的一个应用程序,我们有一个绝对过期的令牌,我们刷新其会话半衰期。当我把它放在本地存储器中时,我为其绝对过期设置了一个计时器。当我刷新令牌并将其放回存储器时,我取消了之前的计时器。如果刷新失败一段时间,则计时器最终会触发。它将强制从本地存储中删除该会话,因为它已过期,它将广播(在我的情况下为ngrx,但在您的情况下为BehaviorSubject)会话已过期。

如果您想要路线更改触发验证,以确保您可以这样做:

<强> auth.service.ts

export class AuthService {
    private loggedIn = new BehaviorSubject<boolean>(false);

    get isLoggedIn() {
        this.loggedIn.next(localStorage.getItem('my-auth-key'));
        return this.loggedIn.asObservable();
    }
}

由于它是一个行为主题,因此您可以在返回之前将新值推送给它。

修改 既然你提到你必须做chrome.storage.sync.get并且它是异步的你可以做以下事情(我没有做任何事情解析存储的任何东西):

<强> auth.service.ts

export class AuthService {
    private loggedIn = new Subject<boolean>();

    get isLoggedIn() {
        chrome.storage.sync.get('my-auth-key', (isAuthenticated) => {
           this.loggedIn.next(isAuthenticated);
        });
        return this.loggedIn.asObservable();
    }
}

请注意,我将其更改为Subject而不是BehaviorSubject。这将强制收件人等待.next电话。这假设您希望每次有人尝试订阅时检查身份验证状态。

更优雅的解决方案是订阅chrome.storage.onChanged以提供您的BehaviorSubject。您可能会在构造函数中设置它。这样的事情......我之前没有使用过这个api所以这只是一般的想法......你可能需要进行空检查或进行解析等等......如果这些值不会从然后你仍然需要一个计时器来移除它们来解雇变化。

<强> auth.service.ts

export class AuthService {
    private loggedIn = new BehaviorSubject<boolean>(false);
    constructor(){
       chrome.storage.onChanged.addListener((changes, namespace) => {
          this.loggedIn.next(change['my-auth-key'].newValue);
       });
    }

    get isLoggedIn() {
        return this.loggedIn.asObservable();
    }
}

答案 1 :(得分:1)

你可以用chrome存储方法创建一个observable:

export class RxChromeStore {
   get(key: string): Observable<any> {
       return Observable.create(obs => {
           let cb = (err, data) => { // use whatever the chrome storage callback syntax is, this is typical cb structure
               if (err) {
                   obs.error(err);
               } else {
                   obs.next(data);
               }
           };
           chrome.storage.sync.get(key, cb);
       }).first();
   }
}

export class AuthService {
    private loggedIn = new BehaviorSubject<boolean>(false);

    get isLoggedIn() {
        return Observable.zip(RxChromeStore.get('your-auth-key'), this.loggedIn.asObservable(), (chromeAuth, authSubj) => chromeAuth || authSubj);
    }
}

你的问题有点含糊,所以我不确定你的确切目标是什么,但这里的基本观点是你总是可以使用create方法创建一个基于回调的soservable,然后你可以对待它像任何其他可观察的一样:

RxChromeStore.get('auth-key').switchMap((auth) => (auth.invalid) ? this.http.get('reauthendpoint') : this.loggedIn.asObservable());

或您需要的任何流

答案 2 :(得分:0)

您可以使用localStorage变量来存储/获取数据。

存储: localStorage.setItem(key,value);
提取localStorage.getItem(key);

这个localStorage变量由您在角度项目中已经拥有的typescript node_module提供。