You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

问题分析与修复

核心问题

  1. 初始RoleGuard逻辑缺失:原代码仅判断路由是否配置了roles,完全没有校验用户角色是否匹配,只要路由有roles配置就直接放行,根本没做权限检查。
  2. 修改后的代码逻辑错误: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 12:42:33