如何使用angular-auth-oidc-client库实现基于角色的权限控制
基于angular-auth-oidc-client的角色授权实现方案
实现思路
不需要修改官方的auto-login-all-routes守卫源码,新增独立的角色校验守卫,和官方守卫组合使用即可。角色守卫只需注入官方公开导出的OidcSecurityService获取用户信息,不会依赖内部未导出的服务。
步骤1:创建自定义角色守卫
执行命令生成守卫文件:ng generate guard guards/role
写入如下逻辑:
import { Injectable } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router'; import { OidcSecurityService } from 'angular-auth-oidc-client'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class RoleGuard implements CanActivate { constructor( private oidcSecurityService: OidcSecurityService, private router: Router ) {} canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable<boolean | UrlTree> { // 从路由配置中读取要求的角色 const requiredRole = route.data['requiredRole']; return this.oidcSecurityService.userData$.pipe( map(userData => { // 无用户信息直接跳转未授权页 if (!userData) { return this.router.parseUrl('/unauthorized'); } // 请根据你的身份提供商返回的userData结构调整角色字段路径 const userRoles = userData['roles'] || userData['realm_access']?.['roles'] || []; if (userRoles.includes(requiredRole)) { return true; } return this.router.parseUrl('/unauthorized'); }) ); } }
步骤2:路由配置组合守卫
在路由配置中将官方登录守卫和自定义角色守卫组合使用,通过路由data传入所需角色:
import { AutoLoginAllRoutesGuard } from 'angular-auth-oidc-client'; import { RoleGuard } from './guards/role.guard'; const routes: Routes = [ { path: 'admin-dashboard', component: AdminDashboardComponent, // 先执行登录校验,再执行角色校验 canActivate: [AutoLoginAllRoutesGuard, RoleGuard], data: { requiredRole: 'admin' } }, { path: 'personal-center', component: PersonalCenterComponent, canActivate: [AutoLoginAllRoutesGuard, RoleGuard], data: { requiredRole: 'normal_user' } }, { path: 'unauthorized', component: UnauthorizedComponent } ];
补充说明
- 如果需要支持多角色校验,可将路由data的
requiredRole改为字符串数组,调整判断逻辑为用户角色是否包含数组中任意一个即可 - 如果是懒加载模块,将守卫配置在
loadChildren对应的路由层级即可,逻辑和普通路由完全一致 - 若角色存储在access token而非userinfo接口返回的用户信息中,可调用
OidcSecurityService.getAccessToken()方法解析token payload获取角色字段
内容的提问来源于stack exchange,提问作者Itori
相关产品推荐
相关产品推荐

