我有一个路由守卫:
import { Injectable } from "@angular/core";
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from "@angular/router";
import { Observable } from "rxjs";
import { ConfigurationService } from "./../configuration.service";
import { LoginServiceService } from '../login-service.service';
import { map } from 'rxjs/operators'
import { of } from 'rxjs';
@Injectable()
export class RoleGuard implements CanActivate {
activate = false;
constructor(private loginService: LoginServiceService,
private router: Router,
private configService:ConfigurationService
) {
}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> | boolean {
return this.loginService.userRights().pipe(
map((userRights) => {
this.filterUserRights(userRights['rights'])
}),
);
}
filterUserRights(userRights:Array<string>):Observable<boolean> {
console.log(userRights)
const requiredRights = ['create_organisation', 'create_tenant', 'create_user'];
if (requiredRights.some((right) => userRights && userRights.includes(right))) {
this.activate = true;
} else {
this.activate = false;
}
return of(this.activate);
}
}
我有一条父路线,如:
{ path: "", redirectTo: "mylearning", pathMatch: "full" },
{
path: "managepeople",
component: ManagepeopleComponent,
canActivate: [RoleGuard],
children: [
{ path: "", redirectTo: "organisations", pathMatch: "full" },
{
path: "organisations",
component: OrganisationsComponent,
data: {
animation: "organisations"
},
},
]
}
我在上级路线管理人员上使用角色保护。问题是当我在浏览器上刷新ex的浏览器时:managepeople / organisations, 它不会转到该路由,而是重定向到根组件url。用户权限来自一项服务,需要从服务器中获取一些服务。 我该如何解决?
我的服务功能:
userRights() {
var uiRolesUrl = this.config.restRequestUrl + "userapi/myrights/";
var observable = this.http.get(uiRolesUrl);
return observable;
}
答案 0 :(得分:1)
如您所见,canActivate可以返回Observable或Promise,它们允许异步操作。因此,您需要以异步方式编写它以处理尚未获取用户角色的情况。像这样:
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
): boolean | Observable<boolean> {
if (this.configService.userRights) {
return this.filterUserRighs(this.configService.userRights);
}
return this.configService.getUserRights.pipe(
map((userRights) => {
return this.filterUserRighs(userRights);
}),
);
}
filterUserRighs(userRights) {
const requiredRights = ['create_organisation', 'create_tenant', 'create_user'];
if (requiredRights.some((right) => userRights && userRights.includes(right))) {
this.activate = true;
} else {
this.activate = false;
}
return this.activate;
}
答案 1 :(得分:0)
这有效:
import { Injectable } from "@angular/core";
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from "@angular/router";
import { Observable } from "rxjs";
import { ConfigurationService } from "./../configuration.service";
import { LoginServiceService } from '../login-service.service';
import { map } from 'rxjs/operators'
import { of } from 'rxjs';
@Injectable()
export class RoleGuard implements CanActivate {
activate = false;
constructor(private loginService: LoginServiceService,
private router: Router,
private configService:ConfigurationService
) {
}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> | boolean {
return this.loginService.userRights().pipe(map((userRights) => {
return this.filterUserRights(userRights['rights']);
}),
)
}
filterUserRights(userRights:Array<string>){
const requiredRights = ['create_organisation', 'create_tenant', 'create_user'];
if (requiredRights.some((right) => userRights && userRights.includes(right))) {
this.activate = true;
} else {
this.activate = false;
}
return this.activate;
}
}