使用 Angular 11 的自定义页面权限
Custom Page Permission using Angular 11
我正在开发一个实现自定义权限的应用程序。有一个基于订阅的权限,我无法在 auth guard 中签入,这将是静态的,我已经实现了权限助手,它检查路由,然后在该路由的用户订阅中签入它,然后重定向到角色上的任何页面允许。它工作正常,但我需要一种更好的方法来使用干净的代码来实现它。这是我的实现
Home Component
import { Component, OnInit } from "@angular/core";
import { Location } from '@angular/common';
import { AuthService } from "src/app/services/apiServices/auth.service";
@Component({
selector: "app-home",
templateUrl: "./home.component.html"
})
export class HomeComponent implements OnInit {
constructor(private readonly location: Location, private readonly authService : AuthService ) {
}
ngOnInit() {
this.authService.getPermission(this.location.path());
}
}
Auth Service Code
getPermission(currentRoute: string) {
this.userPermissions = this.loggedInUserSubscriptionDetails$.subscribe(sub => {
if (sub) {
if (sub.MenuPermissioList.map(x => x.url).indexOf(currentRoute) === -1) {
this.router.navigate(["/finance-analysis/not-authorized"]);
return;
}else{
console.log('exists');
}
}
});
}
此代码基本上是获取当前位置路径,然后在订阅 MenuPermissioList 中检查该路径,如果存在则允许打开页面,否则它会重定向到未经授权的页面。
我不想使用此代码 data : {roles: [ApplicationRolesEnum.CompanyAdmin]} 因为我必须从数据中添加或删除角色才能允许特定页面的用户,它基本上是静态绑定。我在这里添加了这个检查,它工作正常,但我的许可可能因用户而异。这使得维护变得困难。
{
path: "home",
canActivate: [AuthGuard, SubscriptionGuard],data : {roles: [ApplicationRolesEnum.CompanyAdmin, ApplicationRolesEnum.ExternalUser]},
loadChildren: () => import("src/app/pages/dashboard/dashboard.module").then(m => m.DashboardModule)
},
您可以尝试以下方法。我现在没有测试它并且已经把它写下来但它基于我在一个项目中使用的方法。
基本上,您仍然会为此使用 Guard,但会动态地从您的服务加载权限,并根据它们让用户激活页面或重定向到未经授权的页面。 CanActivate 为您订阅 Observable,因此您无需手动管理任何订阅。
import { AuthService } from "src/app/services/apiServices/auth.service";
@Injectable()
export class SubscriptionGuard implements CanActivate {
constructor(
private readonly router: Router,
private readonly authService: AuthService,
) { }
canActivate(activatedRoute: ActivatedRouteSnapshot, routerState: RouterStateSnapshot): Observable<boolean> {
return this.authService.loggedInUserSubscriptionDetails$.pipe(
take(1),
map((sub) => {
if (!sub) {
return false;
}
return sub.MenuPermissioList.map(x => x.url).includes(routerState.url);
}),
tap(hasPermission => hasPermission ? undefined : this.router.navigate(['/finance-analysis/not-authorized']))
);
}
}
编辑:在评论中讨论后更改了提取电流的方式url。
我正在开发一个实现自定义权限的应用程序。有一个基于订阅的权限,我无法在 auth guard 中签入,这将是静态的,我已经实现了权限助手,它检查路由,然后在该路由的用户订阅中签入它,然后重定向到角色上的任何页面允许。它工作正常,但我需要一种更好的方法来使用干净的代码来实现它。这是我的实现
Home Component
import { Component, OnInit } from "@angular/core";
import { Location } from '@angular/common';
import { AuthService } from "src/app/services/apiServices/auth.service";
@Component({
selector: "app-home",
templateUrl: "./home.component.html"
})
export class HomeComponent implements OnInit {
constructor(private readonly location: Location, private readonly authService : AuthService ) {
}
ngOnInit() {
this.authService.getPermission(this.location.path());
}
}
Auth Service Code
getPermission(currentRoute: string) {
this.userPermissions = this.loggedInUserSubscriptionDetails$.subscribe(sub => {
if (sub) {
if (sub.MenuPermissioList.map(x => x.url).indexOf(currentRoute) === -1) {
this.router.navigate(["/finance-analysis/not-authorized"]);
return;
}else{
console.log('exists');
}
}
});
}
此代码基本上是获取当前位置路径,然后在订阅 MenuPermissioList 中检查该路径,如果存在则允许打开页面,否则它会重定向到未经授权的页面。
我不想使用此代码 data : {roles: [ApplicationRolesEnum.CompanyAdmin]} 因为我必须从数据中添加或删除角色才能允许特定页面的用户,它基本上是静态绑定。我在这里添加了这个检查,它工作正常,但我的许可可能因用户而异。这使得维护变得困难。
{
path: "home",
canActivate: [AuthGuard, SubscriptionGuard],data : {roles: [ApplicationRolesEnum.CompanyAdmin, ApplicationRolesEnum.ExternalUser]},
loadChildren: () => import("src/app/pages/dashboard/dashboard.module").then(m => m.DashboardModule)
},
您可以尝试以下方法。我现在没有测试它并且已经把它写下来但它基于我在一个项目中使用的方法。
基本上,您仍然会为此使用 Guard,但会动态地从您的服务加载权限,并根据它们让用户激活页面或重定向到未经授权的页面。 CanActivate 为您订阅 Observable,因此您无需手动管理任何订阅。
import { AuthService } from "src/app/services/apiServices/auth.service";
@Injectable()
export class SubscriptionGuard implements CanActivate {
constructor(
private readonly router: Router,
private readonly authService: AuthService,
) { }
canActivate(activatedRoute: ActivatedRouteSnapshot, routerState: RouterStateSnapshot): Observable<boolean> {
return this.authService.loggedInUserSubscriptionDetails$.pipe(
take(1),
map((sub) => {
if (!sub) {
return false;
}
return sub.MenuPermissioList.map(x => x.url).includes(routerState.url);
}),
tap(hasPermission => hasPermission ? undefined : this.router.navigate(['/finance-analysis/not-authorized']))
);
}
}
编辑:在评论中讨论后更改了提取电流的方式url。