Angular 带有 Promise 和 if 语句的 Auth Guard

Angular Auth Guard with a Promise and if statement

我想使用守卫来决定用户是否可以导航到登录页面,但我知道我的逻辑是错误的,因为 Promise。 请参阅下面的代码。

  canActivate(): boolean | Observable<boolean> | Promise<boolean> {
    if (!this.localStorage.getObject('isInitialized')) {
      this.router.navigate(['/locaties']);
      return true;
    }
    return false;
  }

我知道我做的是错的,但我缺乏关于 promises 的知识来解决这个问题。我需要做什么才能完成这项工作?

这是我的 localstorage.getObject():

  // Returns object
  async getObject(key: string) {
    const ret = await Storage.get({ key: key });
    return JSON.parse(ret.value);
  }

所以这里有一些错误,但我认为承诺不是其中之一。您的函数签名表示您可以选择 return 三种类型之一,

canActivate(): boolean | Observable<boolean> | Promise<boolean>

但你只能 return 一个布尔值,所以你真的可以将其重写为

canActivate(): boolean

但这不是问题所在。没有看到您的路线设置很难说,但如果允许他们请求的路线并且没有必要,您似乎正在重新安排用户路线。当用户已经尝试导航到页面时路由守卫 运行。如果路由守卫 return 为真,则允许进行导航,用户将继续访问路由守卫保护的任何页面。

但是当路由保护 return 为 false 时,您应该指定重定向页面。换句话说,当用户无法访问守卫后的页面时,你想将他们发送到哪里?

一般来说,看起来像这样,

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

    canActivate(state: RouterStateSnapshot): boolean {
        if (!this.localStorage.getObject('isInitialized')) {
            //No need to route here, user will be taken to the route they were trying access
            return true;
        } else {
            //Send the user back to the '/anotherpage' path if they are not logged in
            this.router.navigate(['/anotherpage']);
            return false;
        }
    }
}

然后像这样定义你的路线,

export const appRoutes: Routes = [
    {
        path: 'pageProtectedByAuthGuard',
        component: YourComponent,
        canActivate: [AuthGuard]
    }
];

然后在你的模块中你需要导入那些路由,

@NgModule({
    imports: [RouterModule.forRoot(appRoutes, { enableTracing: false })],
    ...
})

更多关于 CanActivate 的信息:https://angular.io/api/router/CanActivate

答案是

    this.localStorage.getObject('isInitialized').then((res) => {
      if (res == true) {
        this.router.navigate(['/locaties']);
        return false;
      }
    });
    return true;
  }

请记住,当用户想要导航到该页面时,会触发 auth guard。没必要弄得比这更复杂

如果您想在 can activate 方法中使用基于异步结果的条件,那么您可以使用 Promise。如果您打算使用本地存储中的直接值,则无需使用 promise。您可以像下面这样使用 promise...

  canActivate(): boolean | Observable<boolean> | Promise<boolean> {
    return new Promise(() => {
    if (!this.localStorage.getObject('isInitialized')) {
      this.router.navigate(['/locaties']);
      // Do not allow the route
      resolve(false);
    } else {
      // Allow the route
      resolve(true);
     }
    
    });
  }