angular - 如何在 Angular 中使用 AuthGuard 为两个不同的用户角色提供相同菜单的路由访问权限?
问题描述
我有一个具有三个用户角色的应用程序:ROLE_USER、ROLE_MODERATOR 和 ROLE_ADMIN,如下所示:
export enum Role {
User = 'ROLE_USER',
Moderator = 'ROLE_MODERATOR',
Admin = 'ROLE_ADMIN'
}
我有一个名为“配置文件”的菜单,ROLE_MODERATOR 和 ROLE_ADMIN 可以访问它。成功登录版主和管理员后可以看到此菜单。我正在使用 AuthGuard 限制未经授权的用户访问配置文件菜单,在这种情况下,只有版主和管理员可以访问它。我在我的 app.module.ts 文件中放置了配置文件菜单的 AuthGuard,如下所示:
path: 'profile', component: ProfileComponent, canActivate: [AuthGuardService], data: { roles: [Role.Admin, Role.Moderator] }, pathMatch: 'full' }
我的用户类如下:
export class User {
username: string;
password: string;
role: Role;
}
我的 AuthGuard 类如下:
export class AuthGuardService implements CanActivate {
isLoggedIn: boolean;
constructor(private router: Router,
private tokenService: TokenStorageService,
private auth: AuthService) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const currentUser = this.tokenService.getUser();
this.isUserLoggedIn = this.tokenService.getToken();
if (this.isLoggedIn) {
if (currentUser.roles == 'ROLE_ADMIN' || currentUser.roles == 'ROLE_MODERATOR') {
return true;
}
this.router.navigate(['/']);
return false;
}
}
isUserLoggedInn() {
if (this.tokenService.getToken()) {
this.isLoggedIn = true;
}
}
}
在上面的代码中有一个简单的逻辑,它会检查用户是否登录。如果用户登录,它将检查当前用户角色。如果用户的角色是管理员或版主,它应该能够从他们各自的帐户访问配置文件菜单,我希望我已经在 app.module.ts 类中正确配置了配置文件菜单。但它没有按预期工作,所以我在这里做错了。任何帮助或建议都会很棒。提前致谢。
解决方案
我看到您正在使用“数据”通过路由传递“允许的角色”。但是,您并没有在警卫中使用它。
data: { roles: [Role.Admin, Role.Moderator] }
您可以通过执行以下操作使任何角色(以及未来角色)的警卫动态化:
export class AuthGuardService implements CanActivate {
isLoggedIn: boolean;
constructor(private router: Router,
private tokenService: TokenStorageService,
private auth: AuthService) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
// Gets the roles from route data
const roles = route.data['roles'] as Array<string>;
const currentUser = this.tokenService.getUser();
this.isUserLoggedIn = this.tokenService.getToken();
if (this.isUserLoggedIn) {
// Considering currentUser.roles is a single value and not an array
for (let i = 0; i < roles.length; i++) {
if (currentUser.roles == roles[i]) {
return true
}
}
// Considering currentUser.roles is an array of roles allotted to the user, then uncomment the below code
// for (let i = 0; i < roles.length; i++) {
// if (currentUser.roles.findIndex(x => x.roleName == roles[i]) != -1) {
// return true;
// }
// }
this.router.navigate(['/']);
return false;
}
}
}
推荐阅读
- android-studio - Android Studio:项目结构层次结构中的子模块
- r - 密度图 ggplot 错误返回缺失的美学错误
- python - Python Selenium:有时无法在 iframe 中获取内容
- cytoscape - 如何实现新的节点形状
- google-play - Expo 托管项目密钥库文件和 Google Play 上传密钥库之间的区别
- c++11 - 使用 pybind11 动态加载 libpython
- java - 使用打包的 JRE 编译为 linux 可执行文件
- ajax - 当您期望空结果时,如何防止从 java 服务器端返回 400 代码?
- javascript - 在 javascript 中构建表格并在 1 个单元格中进行粗体测试
- dart - 我想创建每个字母大写的随机英文单词,但我失败了,尽管我遵循与指令显示完全相同的代码