我正在尝试在具有多种角色类型的基础项目上实施基于角色的访问控制Angular
我想获得用户的数据(角色属性)在CanActivate
接口检查用户是否有权访问受保护routes
的guard
,但BehaviouralSubject
在收到的最新值后不更新初始状态API
。
因此,我在身份验证服务中获取用户的数据,然后将接收到的值传递给userRole
主题,但是更新的属性(BehaviouralSubject)在保护文件中不可用。
服务认证
constructor() {
let localToken: string
if (localStorage.getItem('token')) {
localToken = localStorage.getItem('token')
this.getUserInfo(localToken)
}
}
userRole = new BehaviorSubject(null)
userRole$ = this.userRole.asObservable()
// called in constructor of a auth. service (every time when user called)
// and after login as well, so user's data always available.
getUserInfo(data) {
this.requestService
.post('GET_USER_INFO', data)
.subscribe((response: ILoggedInUser) => {
// data from API {email: "[email protected]", userName: "ccc", role: "viewer"}
this.userRole.next(response.user)
})
}
验证卫士
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.authService.userRole$.pipe(
map(member => {
if (member) {
// check if route is restricted by role
if (
route.data.roles &&
route.data.roles.indexOf(member.role) === -1
) {
// role not authorised so redirect to home page
this.router.navigate(['/login'])
return false
}
return true
} else {
this.router.navigate(['/login'])
return false
}
}),
)
}
这是路由:
const routes: Routes = [
{
path: 'home',
component: HomeComponent,
},
{
path: 'admin',
component: AdminComponent,
canActivate: [AuthGuard],
data: { roles: ['admin'] },
},
{
path: 'editor',
component: EditorsComponent,
canActivate: [AuthGuard],
data: { roles: ['admin', 'editor'}
},
{
path: 'viewer',
component: ViewersComponent,
canActivate: [AuthGuard],
data: { roles: ['admin', 'viewer'] },
}
]
我尝试另一种方法为好,(例如,使用订阅),但是当我尝试subscribe
以userRole
主题是这样的:
return this.authService.userRole.subscribe((member) => {
.......
.......
}
则类型'AuthGuard'中有一个属性'canActivate'无法分配给基本类型'CanActivate'错误中的同一属性,因为Subscription
类型不能分配给type boolean
。
因此,你可以给任何提示或建议的处理更好的方式RBAC在angular
与观测。
聚苯乙烯
我见过的解决方案有localStorage
,但我不希望保留用户数据(除令牌)那里。
问题在于,userRole$
可观察对象null
最初会发出,因为它已订阅到userRole BehaviorSubject
,后者将null作为参数。
因此,userRole $ observable等于获取更新的null,并且AuthGuard类型的属性canActivate无法返回null。
因此,在传递对象到映射之前,应该使用filter()运算符,以摆脱null。
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.authService.userRole$.pipe(
filter(member => !!member), // Filter NULL value here before sending object further
map(member => {
....
return true
} else {
....
}
)
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句