我正在尝试基于用户的权限实施安全路由。没有特定权限的用户无法访问该路由。这就是我在路由中传递正确名称的原因(惰性模块路由)。但是,我发现获取懒惰的路线数据有点复杂。我必须订阅路由器事件。但是,订阅后,我找不到将 false 或 true 返回到 Canactivate 的方法。
这是我的 canActivate 代码:
canActivate() {
this.router.events
.pipe(
filter((event) => event instanceof NavigationEnd),
map(() => this.activatedRoute),
map((route) => {
while (route.firstChild) {
route = route.firstChild;
}
return route;
}),
mergeMap((route) => route.data))
.subscribe((event) => {
const right = event.right; // getting the right name from the route data.
const rights = this.localStorageService.getLocalStorageItem('rights');
if (right) {
if (rights.includes(right)) {
// I need to return true from here
} else {
// I need to return false from here
}
}
});
}
而且,这是我的路线代码:
const routes: Routes = [{ path: ':id', component: ProfileComponent,
data: { right: 'VIEW_PROFILE' }, canActivate: [RightRouteGuardService]}];
答案 0 :(得分:1)
Angular 路由守卫可以返回 Observable<boolean> | Promise<boolean> | boolean
。我想你想返回一个布尔值,但如果我是你,我会返回 Observable<boolean>
。
试试这个:
canActivate(): Observable<boolean> {
return this.router.events
.pipe(
filter((event) => !!event), // !! add this filter !!
filter((event) => event instanceof NavigationEnd),
map(() => this.activatedRoute),
map((route) => {
while (route.firstChild) {
route = route.firstChild;
}
return route;
}),
mergeMap((route) => route.data),
// map will return true false for us
map(event => {
const right = event.right; // getting the right name from the route data.
const rights = this.localStorageService.getLocalStorageItem('rights');
if (right) {
if (rights.includes(right)) {
return true;
} else {
return false;
}
}
}),
);
}
你不需要再订阅了,这个 observable 的第一次发射就会为你返回 true 和 false。
========================== 编辑 ==================== ======
不要注入路由器并侦听事件,因为路由器尚未完成导航并且您的 filter
的 NavigationEnd
将不允许它继续进行,并且当时没有任何事件.
我已经解决了这个问题:
import { Injectable } from "@angular/core";
import {
ActivatedRouteSnapshot,
CanActivate,
RouterStateSnapshot
} from "@angular/router";
@Injectable({
providedIn: "root"
})
export class RightRouteGuardService implements CanActivate {
constructor() {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean{
let right = route.data.right;
console.log({ right });
const rights = ['VIEW_STUDENT'];
if (rights.includes(right)) {
return true;
} else {
return false;
}
}
}
canActivate
方法接受两个属性,您可以使用这些属性读取相关路由的数据属性。
我受到了这个post的启发。