Why can't I get the value of storage using async for AuthGuard?

tim*_*vin 1 ionic-framework angular ionic4

I'm trying to do a very simple login in my Ionic 4 app. When a user logs in I set a token in storage. This is working.

I'm using an Auth Guard to check against one page in the app, so if the token is set in storage, the user can view the page. Otherwise they are redirected to the login page.

My problem is that I'm completely stuck in async hell; I just can't figure it out. I'm trying to do a simple check: is the token set in storage or not. if yes, return true, if not, return false.

The problem I'm experiencing is that, even after successfully logging in and storing the token, when trying to access the restricted page I'm still redirected to the login page; I'm assuming it's because of not properly using async in my guard.

What am I doing wrong?

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot } from '@angular/router';
import { Storage } from '@ionic/storage';

@Injectable({
    providedIn: 'root'
})
export class AuthGuard implements CanActivate {

    authenticated: boolean;

    constructor(
        private router: Router,
        private storage: Storage
    ) {
        this.getToken();
    }

    canActivate(route: ActivatedRouteSnapshot): boolean {

        if (this.authenticated) {
            return true;
        }

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

    async getToken() {
        await this.storage.get('token').then(res => {
            if (res) {
                this.authenticated = true;
            } else {
                this.authenticated = false;
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 6

我认为问题在于您正在检查构造函数中的存储,并且在服务初始化时您已注销,因此this.authenticated总是false. 您应该做的是,每次导航路线时都执行此检查。

试试这个代码-

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot } from '@angular/router';
import { Storage } from '@ionic/storage';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {

  constructor(
    private router: Router,
    private storage: Storage
  ) {
  }

  canActivate(route: ActivatedRouteSnapshot): Promise<boolean> {

    return this.storage.get('token').then(res => {
      if (res) {
        return true;
      }

      this.router.navigate(['/login']);
      return false;
    });
  }
}
Run Code Online (Sandbox Code Playgroud)