[英]How can I use the result of an http request in a guard implementing CanActivate in Angular 9?
[英]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.