[英]In Angular -> how to check if the user has permission using role-based access with the role save in the data base
I'm trying to make a role-based access for my app in angular, and I need some help because I'm newbie in angular ...我正在尝试使用 angular 为我的应用程序进行基于角色的访问,我需要一些帮助,因为我是 angular 的新手......
First this is what I have in the route where I establish which roles can access it...首先,这是我在建立哪些角色可以访问它的路线中所拥有的......
from app-routing.module.ts来自 app-routing.module.ts
{
path: 'profile',
component: ComunityComponent,
canActivate: [AuthGuard],
data: {
allowedRoles: ['admin', 'user']
}
},
Second I use the canActivate function to check if the user can access the route or not.其次,我使用 canActivate 函数来检查用户是否可以访问路由。 from auth.guard.ts来自 auth.guard.ts
private hasAccess: boolean;
constructor(private router: Router, private auth: AuthService) {}
canActivate(next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
const allowedRoles = next.data.allowedRoles;
if (localStorage.getItem('currentUser')) {
return this.checkAccess(localStorage.getItem('currentUser'), allowedRoles);
}
this.router.navigate(['/login'], {queryParams: {returnUrl: state.url}});
return false;
}
Third, I develop the function accessLoginToken, that will find the role of the logged user through an httpclient.get service which returns an array with the roles assigned to the user.第三,我开发了函数 accessLoginToken,它将通过 httpclient.get 服务找到登录用户的角色,该服务返回一个包含分配给用户的角色的数组。 Example {success: true, roles:['user']}
from auth.service.ts示例{success: true, roles:['user']}
来自 auth.service.ts
accessLoginToken(token: string) {
const check = '/users/access';
const httpOptions = {
headers: new HttpHeaders({
'Authorization': 'Bearer ' + token,
})
};
return this.http.get<any>('/api' + check, httpOptions).pipe(
catchError(err => this.handleError('accessLoginToken', err))
);
}
Fourth in the function checkAccess
, I compare it with those of the route and if they match I allow the access otherwise not.在function checkAccess
中的第四个,我将它与路由的那些进行比较,如果它们匹配,我允许访问,否则不允许访问。 from auth.guard.ts来自 auth.guard.ts
private checkAccess(token: string, allowedRoles: string[]): boolean {
this.hasAccess = false;
this.auth.accessLoginToken(token).subscribe(data => {
if (data.success) {
data.roles.forEach(rol => {
if (allowedRoles.findIndex(rols => rols === rol) >= 0) {
this.hasAccess = true;
}
});
}
}, (error) => {
console.log(error);
});
console.log(this.hasAccess);
return this.hasAccess;
}
The main problem is that I can not get the httpclient subscribe to change the value of the hasAccess variable to true to allow access.主要问题是我无法让 httpclient 订阅将 hasAccess 变量的值更改为 true 以允许访问。 Even when the code this.hasAccess = true;
即使当代码this.hasAccess = true;
is executed the function returns false执行该函数返回false
By the way I do not like the idea of saving the role in a session variable like the access_token so I'm trying to keep it in the database...顺便说一句,我不喜欢将角色保存在像 access_token 这样的会话变量中的想法,所以我试图将它保存在数据库中......
any help on the subject will be appreciated .. thanks对这个问题的任何帮助将不胜感激..谢谢
You're correct, the checkAccess
function finishes before the async api call finishes, so false
is always returned.你是对的, checkAccess
函数在异步 api 调用完成之前完成,所以总是返回false
。 Instead you should pass the observable to the canActivate method.相反,您应该将 observable 传递给 canActivate 方法。
private checkAccess(token: string, allowedRoles: string[]): boolean {
this.hasAccess = false;
return this.auth.accessLoginToken(token).pipe(
map(data => {
if (data.success) {
data.roles.forEach(rol => {
if (allowedRoles.findIndex(rols => rols === rol) >= 0) {
this.hasAccess = true;
}
});
}
return this.hasAccess;
})
)
}
Because an observable is returned to the canActivate
method, the guard will subscribe to the observable and wait for a true or false result.因为一个 observable 被返回给canActivate
方法,守卫将订阅该 observable 并等待一个真或假的结果。
Your problem lies in the fact that you return this.hasAccess while the accessLoginToken is still running.您的问题在于您在 accessLoginToken 仍在运行时返回 this.hasAccess 。 You can return an observable to angular guard.您可以将 observable 返回给 angular Guard。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.