[英]Angular AuthorizeGuard Roles
I'm trying to implement a role based system on my application and I have the following:我正在尝试在我的应用程序上实现基于角色的系统,并且我有以下内容:
authorize.service.ts授权.service.ts
public isAuthenticated(): Observable<boolean> {
return this.getUser().pipe(map(u => !!u));
}
public hasRole(roles: Array<string>): Observable<boolean> {
return this.getUser().pipe(map(u => {
if (!!!u) {
return false;
}
const role = u['http://schemas.microsoft.com/ws/2008/06/identity/claims/role'];
return roles.some(r => r === role);
}));
}
app.routing.ts app.routing.ts
...
{ path: 'list', component: ListComponent, canActivate: [AuthorizeGuard], data: { title: 'List', roles: [Role.Admin, Role.Developer, Role.Guest, Role.User]} }
...
And I would like to have the following logic on my AuthorizeGuard :我想在我的AuthorizeGuard上有以下逻辑:
If isn't authenticated navigate to the login page.如果未通过身份验证,请导航到登录页面。
If is logged in and has the required role navigate to the page otherwise navigate to a "forbidden" page.如果已登录并具有所需的角色导航到该页面,否则导航到“禁止”页面。
I have this code on my canActivate:我的 canActivate 上有这个代码:
canActivate(
_next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
this.authorize.isAuthenticated().subscribe(isAuthenticated => {
if (isAuthenticated) {
this.authorize.hasRole(roles).subscribe(hasRole => {
if (hasRole) {
return true;
} else {
this.router.navigate(['forbidden']);
}
});
} else {
this.router.navigate(ApplicationPaths.LoginPathComponents, {
queryParams: {
[QueryParameterNames.ReturnUrl]: state.url
}
});
}
});
return true;
}
But it doesn't work because of the subscribers.但由于订阅者,它不起作用。
Is there anyway to make wait for the result and return it instead of always return true?无论如何要等待结果并返回它而不是总是返回true?
Thanks谢谢
You can't mix 2 subscribe and return true in the end, cause it always is true(last return).您不能混合 2 订阅并最终返回 true,因为它始终为 true(最后返回)。
You need return Observable<boolean>
from the start and chain it to have Observable of false || true
您需要从一开始就返回
Observable<boolean>
并将其链接到 Observable 为false || true
false || true
at the end最后
false || true
This code is changed in this editor, so it maybe won't work from the start, but you would get the idea of chaining此代码在此编辑器中已更改,因此它可能从一开始就不起作用,但您会了解链接的想法
return this.authorize.isAuthenticated().pipe(
concatMap(isAuth => isAuth ? this.authorize.hasRole(roles) : throwError('NO_AUTH')),
concatMap(hasRole => hasRole ? of(true) : throwError('NO_ROLE')),
catchError(error => {
const isAuthError = error === 'NO_AUTH';
if (isAuthError) {
this.router.navigate(ApplicationPaths.LoginPathComponents, {
queryParams: {
[QueryParameterNames.ReturnUrl]: state.url
}
});
} else {
this.router.navigate(['forbidden']);
}
return of(false);
}),
);
ps approach with catchError
could be reworked to some other带有
catchError
的 ps 方法可以改写为其他方法
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.