Angular Route Guards: Или против И

Я работаю над защитой интерфейса моего приложения Angular с помощью средств защиты маршрута. Работая с ними в прошлом и исследуя онлайн, добавление нескольких охранников к маршруту требует, чтобы все они вернули true, чтобы разрешить доступ.

Но что, если я хочу, чтобы только один вернул true, чтобы разрешить доступ? (как || вместо &&)

Например, мои охранники маршрута ищут определенные роли в токене пользователя:

@Injectable()
export class ActiveRoleGuard implements CanActivate {
    constructor(private sessionService: SessionService, private router: Router) { }


    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        let token = this.sessionService.getToken();

        if (!token) {
             return false;
        }

        if (token.role.toLowerCase().indexOf("active") < 0) {
            this.router.navigate(["/issue"]);
            return false;
        }

        return true;
    }
}

А также

@Injectable()
export class AdminRoleGuard implements CanActivate {
    constructor(private sessionService: SessionService, private router: Router) { }


    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        let token = this.appSessionService.getToken();

        if (!token) {
            return false;
        }

        if (token.role.toLowerCase().indexOf("admin") < 0) {
            this.router.navigate(["/issue"]);
            return false;
        }

        return true;
    }
}

Если бы я обычно объединял их в модуле маршрутизатора, это было бы что-то вроде...

{path: "someroute", component: SomeComponent, canActivate: [ActiveRouteGuard, AdminRouteGuard]}

... но это потребовало бы, чтобы пользователь был одновременно Active и Admin, Но что, если я хотел навязать Active и либо Admin или Manager?

Это просто реализовать в API следующим образом:

[Authorize(Roles = "Active")]
[Authorize(Roles = "Admin, Manager")]
public class SomeController : ApiController

но как мне сделать это в Angular?

1 ответ

Вместо того, чтобы иметь два отдельных CanActivate реализации, вы можете просто использовать одну версию, которая может быть "настроена". Для этого вы можете воспользоваться data собственностью Route, Например, в ваших маршрутах вы можете сделать что-то вроде:

{
    path: "someroute",
    component: SomeComponent,
    canActivate: [RoleRouteGuard],
    data: {
        requiredRoles: ["Role1", "Role2", "Role3"]
    }
}

Используя это, вы можете взять один из ваших существующих CanActivate реализации, и сделать его более общим. Вы можете получить доступ к requiredRoles собственность от data через ActivatedRouteSnapshot, например:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    const requiredRoles = route.data.requiredRoles;
    ....

Получив это, вы можете проверить, находится ли роль токена в массиве и т. Д. И т. Д.

Если у вас всегда требуется Active роль, а затем один из Admin или же Manager роль, вы также можете расширить это, чтобы иметь несколько data свойства. Например, вы могли бы иметь requiredRoles а также atLeastOneOfRoles и обновите свою логику, чтобы обработать это соответственно... Есть много вариантов на данный момент, но я не думаю, что вам понадобится помощь с этим.

Другие вопросы по тегам