繁体   English   中英

Angular 11 可以根据 HTTP 请求的结果激活 Guard

[英]Angular 11 canActivate Guard depending on the result of a HTTP req

我想阻止普通用户访问/players/scores ,如果他们试图这样做,它应该将他们重定向到/home 只有管理员可以访问其他路由。 我的问题是,指定用户是否为管理员的数据来自异步 function。 在保护文件中: this.getService.getUserRoles()返回用户的角色(admin 是一个角色)。

    // to check wether user is admin or not
   async isAdmin(): Promise<boolean> {
     if (JSON.stringify(await this.getService.getUserRoles()).includes("admin")) {
      return true;
    }
    return false;
  }

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot) {
    const path: string = route.paramMap.get('path');
    if (!(this.isAdmin())) {
      if (path === "players" || path === "scores") {
        // router: Router
        this.router.navigate(['/home']);
        return false;
      }
    }
    return true;
  }

我确实将canActivate:[RoutesGuard]添加到 app-routing 模块中的两个路由。 有什么想法有什么问题吗?

我正在使用这个后卫

import { Injectable } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { AdvancedRouter } from '@mintplayer/ng-router';
import { AccountService } from '../../services/account/account.service';

@Injectable({
  providedIn: 'root'
})
export class IsInRoleGuard implements CanActivate {
  constructor(
    private accountService: AccountService,
    private router: AdvancedRouter,
  ) {
  }

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.accountService.currentRoles().then((roles) => {
      let routeRoles = <string[]>next.data.roles;
      let intersect = roles.filter(r => routeRoles.indexOf(r) > -1);
      return intersect.length > 0;
    }).catch((error: HttpErrorResponse) => {
      this.router.navigate(['/account', 'login'], {
        queryParams: {
          return: state.url
        }
      });
      return false;
    });
  }
  
}

这是我正在实施警卫的 RoutingModule:

const routes: Routes = [
  { path: '', loadChildren: () => import('./list/list.module').then(m => m.ListModule) },
  { path: ':id/:name', loadChildren: () => import('./show/show.module').then(m => m.ShowModule) },
  { path: 'create', loadChildren: () => import('./create/create.module').then(m => m.CreateModule), canActivate: [IsInRoleGuard], canDeactivate: [HasChangesGuard], data: { roles: ['Blogger'] } },
  { path: ':id/:name/edit', loadChildren: () => import('./edit/edit.module').then(m => m.EditModule), canActivate: [IsInRoleGuard], canDeactivate: [HasChangesGuard], data: { roles: ['Blogger'] } },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class BlogRoutingModule { }

你可以从你的canActivate方法中返回Promise<boolean>

您应该从 canActivate 保护中返回Observable ,否则 Angular 将不会等待 API 调用完成并继续其他操作。

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {
    return this.getService.getUserRoles()
      .pipe(
        map(resp => {              
          if (allowed) return true;
          else {
            // return false and navigate to home
            this.router.navigateByUrl(`home`);
            return false;
          }
        })
      );
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM