Angular 15角色路由权限问题:无权限仍可访问及日志输出需求
Angular 15 路由权限守卫问题
使用Angular 15配置了路由权限守卫,整体功能正常,但存在一个问题:当用户没有CompanyRole权限时,仍能打开对应页面。希望在用户无权限时通过console.log()输出提示信息,研究一周仍未解决,相关代码如下:
app-routing.module.ts
const routes: Routes = [ { path: '', component: AppLayoutComponent, children: [ { path: '', loadChildren: () => import('./applications/components/dashboard/dashboard.module').then(m => m.DashboardModule), canActivate: [RoleGuard], data: {roles: ['DashboardRole', 'AdminRole'] } }, { path: 'company', loadChildren: () => import('./applications/components/company/company.module').then(m => m.CompanyModule), canActivate: [RoleGuard], data: {roles: ['CompanyRole'] }}, { path: 'inventory', loadChildren: () => import('./applications/components/inventory/inventory.module').then(m => m.InventoryModule) }, { path: 'category', loadChildren: () => import('./applications/components/category/category.module').then(m => m.CategoryModule), canActivate: [RoleGuard], data: {roles: ['CategoryRole'] }}, { path: 'brand', loadChildren: () => import('./applications/components/brand/brand.module').then(m => m.BrandModule), canActivate: [RoleGuard], data: {roles: ['BrandRole'] } } ], }, { path: 'auth', loadChildren: () => import('./applications/components/auth/auth.module').then(m => m.AuthModule)}, { path: 'notfound', component: NotfoundComponent, canActivate: [RoleGuard]}, //AuthGuard { path: '**', redirectTo: '/notfound', canActivate: [RoleGuard]} //AuthGuard ];
RoleGuard 初始代码
import { Injectable } from '@angular/core'; import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree} from '@angular/router'; import {AuthService} from "../service/auth/auth.service"; import {Observable} from "rxjs"; @Injectable({ providedIn: 'root' }) export class RoleGuard { constructor(private service: AuthService, private route: Router) { } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { //if(this.service.IsLoggedIn()) { console.log('RoleGuard: login olundu'); const userRoles = this.service.getRoles(); console.log(userRoles); if (userRoles) { // check if route is restricted by role const { roles } = route.data; if (!roles) { // role not authorized so redirect to home page //this.route.navigate(['']); console.log(roles) console.log(roles.includes(userRoles)) console.log('RoleGuard: user not authorized') return false; } // authorized so return true console.log('RoleGuard: user authorized') return true; } console.log('RoleGuard: login değil'); //this.route.navigate(['auth/login']) this.route.navigate(['auth/login'], { queryParams: { returnUrl: state.url } }); return false; //} else { // console.log('RoleGuard: not login'); // this.route.navigate(['auth/login']) // return false; //} } }
AuthService
getRoles() { const loginToken = window.sessionStorage.getItem('access_permission_token') || ''; const _extractedToken=loginToken.split('.')[1]; const _atobData=atob(_extractedToken); const _finalData=JSON.parse(_atobData); return _finalData.resource_access.api_inventory.roles; }
尝试修改后的canActivate方法(授权后仍返回false)
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { const user = this.service.getRoles(); if (user) { console.log(route.data['roles']) console.log(user) // check if route is restricted by role if (route.data['roles'] && route.data['roles'].indexOf(user) === -1) { // role not authorised so redirect to home page console.log('false') this.route.navigate(['/']); return false; } console.log('true') // authorised so return true return true; } // not logged in so redirect to login page with the return url this.route.navigate(['auth/login'], { queryParams: { returnUrl: state.url } }); return false; }
问题分析与修复
核心问题
- 初始RoleGuard逻辑缺失:原代码仅判断路由是否配置了
roles,完全没有校验用户角色是否匹配,只要路由有roles配置就直接放行,根本没做权限检查。 - 修改后的代码逻辑错误:
getRoles()返回的是角色数组,但你用indexOf(user)去查找整个数组是否在路由要求的角色列表里,这必然不匹配,导致授权用户也被拒绝。
修复后的RoleGuard代码
import { Injectable } from '@angular/core'; import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from '@angular/router'; import {AuthService} from "../service/auth/auth.service"; @Injectable({ providedIn: 'root' }) export class RoleGuard implements CanActivate { constructor(private service: AuthService, private router: Router) { } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { console.log('RoleGuard: 用户已登录'); const userRoles = this.service.getRoles(); console.log('当前用户角色:', userRoles); // 校验用户角色是否有效 if (!userRoles || !Array.isArray(userRoles)) { console.log('RoleGuard: 用户无有效角色,跳转登录页'); this.router.navigate(['auth/login'], { queryParams: { returnUrl: state.url } }); return false; } const requiredRoles = route.data['roles']; // 路由无权限限制时直接放行 if (!requiredRoles || !Array.isArray(requiredRoles)) { console.log('RoleGuard: 路由无权限限制,允许访问'); return true; } // 检查用户是否拥有至少一个所需角色 const hasPermission = userRoles.some(role => requiredRoles.includes(role)); if (hasPermission) { console.log('RoleGuard: 用户拥有权限,允许访问'); return true; } else { console.log(`RoleGuard: 用户无权限,需要角色: ${requiredRoles.join(', ')}`); // 可根据需求跳转到首页或无权限页面 this.router.navigate(['/']); return false; } } }
关键修复点
- 明确实现
CanActivate接口,符合Angular规范 - 增加用户角色有效性校验,避免空值或非数组导致的错误
- 使用
some()+includes()组合,正确判断用户是否拥有所需角色 - 无权限时输出清晰的控制台提示信息
- 修正路由无
roles配置时的逻辑:原代码错误拒绝访问,现在改为直接放行(匹配你的inventory页面无权限限制的配置)
内容的提问来源于stack exchange,提问作者fatihgun
相关产品推荐
相关产品推荐

