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

基于Fuse框架的Angular Admin与User路由权限配置问题

Angular Fuse框架下Admin/User角色路由权限与登录跳转配置方案

1. 完善角色鉴权逻辑(核心)

现有AuthGuard仅校验登录状态,未区分角色。需扩展逻辑,校验用户角色是否匹配路由要求:

// auth.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { AuthService } from 'app/core/auth/auth.service';

@Injectable({providedIn: 'root'})
export class AuthGuard implements CanActivate {
    constructor(
        private _authService: AuthService,
        private _router: Router
    ) {}

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        const user = this._authService.currentUserValue;
        
        if (user) {
            // 读取路由要求的角色列表
            const requiredRoles = route.data['roles'] as string[];
            // 无角色要求或角色匹配,允许访问
            if (!requiredRoles || requiredRoles.includes(user.role)) {
                return true;
            }
            // 角色不匹配,跳转至对应角色首页
            this._router.navigate([user.role === 'admin' ? '/admin/dashboard' : '/user/dashboard']);
            return false;
        }

        // 未登录,跳转登录页并记录原路径
        this._router.navigate(['/sign-in'], { queryParams: { returnUrl: state.url } });
        return false;
    }
}

2. 重构路由结构,隔离角色专属路由

清理原有混放的路由配置,严格拆分Admin与User的专属路由,避免权限泄漏:

const routes: Route[] = [
    // 默认跳转首页
    {path: '', pathMatch: 'full', redirectTo: 'home'},

    // 登录后动态中转路由
    {path: 'signed-in-redirect', pathMatch: 'full', redirectTo: ''},

    // 公共访问路由(无需登录)
    {
        path: '',
        component: LayoutComponent,
        data: {layout: 'empty'},
        children: [
            {path: 'home', loadChildren: () => import('app/modules/landing/home/home.module').then(m => m.LandingHomeModule)},
            {path: 'sign-out', loadChildren: () => import('app/modules/auth/sign-out/sign-out.module').then(m => m.AuthSignOutModule)},
            {path: 'unlock-session', loadChildren: () => import('app/modules/auth/unlock-session/unlock-session.module').then(m => m.AuthUnlockSessionModule)},
        ]
    },

    // 未登录专属Auth路由(带NoAuthGuard拦截已登录用户)
    ...(environment.allowSignUp ? [
        {
            path: '',
            canActivate: [NoAuthGuard],
            canActivateChild: [NoAuthGuard],
            component: LayoutComponent,
            data: {layout: 'empty'},
            children: [
                {path: 'confirmation-required', loadChildren: () => import('app/modules/auth/confirmation-required/confirmation-required.module').then(m => m.AuthConfirmationRequiredModule)},
                {path: 'forgot-password', loadChildren: () => import('app/modules/auth/forgot-password/forgot-password.module').then(m => m.AuthForgotPasswordModule)},
                {path: 'reset-password', loadChildren: () => import('app/modules/auth/reset-password/reset-password.module').then(m => m.AuthResetPasswordModule)},
                {path: 'sign-in', loadChildren: () => import('app/modules/auth/sign-in/sign-in.module').then(m => m.AuthSignInModule)},
                {path: 'sign-in-transition', loadChildren: () => import('app/modules/auth/sign-in-transition/sign-in-transition.module').then(m => m.AuthSignInTransitionModule)},
                {path: 'sign-up', loadChildren: () => import('app/modules/auth/sign-up/sign-up.module').then(m => m.AuthSignUpModule)},
                {path: 'sign-up-confirmation', loadChildren: () => import('app/modules/auth/sign-up-confirmation/sign-up-confirmation.module').then(m => m.AuthSignUpConfirmationModule)},
            ]
        }
    ] : [
        {
            path: '',
            canActivate: [NoAuthGuard],
            canActivateChild: [NoAuthGuard],
            component: LayoutComponent,
            data: {layout: 'empty'},
            children: [
                {path: 'confirmation-required', loadChildren: () => import('app/modules/auth/confirmation-required/confirmation-required.module').then(m => m.AuthConfirmationRequiredModule)},
                {path: 'forgot-password', loadChildren: () => import('app/modules/auth/forgot-password/forgot-password.module').then(m => m.AuthForgotPasswordModule)},
                {path: 'reset-password', loadChildren: () => import('app/modules/auth/reset-password/reset-password.module').then(m => m.AuthResetPasswordModule)},
                {path: 'sign-in', loadChildren: () => import('app/modules/auth/sign-in/sign-in.module').then(m => m.AuthSignInModule)},
                {path: 'sign-in-transition', loadChildren: () => import('app/modules/auth/sign-in-transition/sign-in-transition.module').then(m => m.AuthSignInTransitionModule)},
            ]
        }
    ]),

    // Admin专属路由(仅Admin角色可访问)
    {
        path: 'admin',
        canActivate: [AuthGuard],
        canActivateChild: [AuthGuard],
        component: LayoutComponent,
        data: {
            layout: 'empty',
            roles: ['admin']
        },
        children: [
            {path: 'dashboard', loadChildren: () => import('app/modules/admin/dashboards/analytics/analytics.module').then(m => m.AnalyticsModule)},
            {path: 'solarmanagement/:id', loadChildren: () => import('app/modules/admin/pages/userassigned/userassigned.module').then(m => m.UserassignedModule)},
            {path: 'settings', loadChildren: () => import('app/modules/admin/pages/settings/settings.module').then(m => m.SettingsModule)},
            {path: 'usergroup', loadChildren: () => import('app/modules/admin/pages/usergroup/usergroup.module').then(m => m.UsergroupModule)},
            {path: 'solarmanagement', loadChildren: () => import('app/modules/admin/pages/solarmanagement/solarmanagement.module').then(m => m.SolarmanagementModule)},
            {path: '404-not-found', pathMatch: 'full', loadChildren: () => import('app/modules/admin/pages/error/error-404/error-404.module').then(m => m.Error404Module)},
            {path: '**', redirectTo: '404-not-found'},
        ]
    },

    // User专属路由(仅User角色可访问)
    {
        path: 'user',
        canActivate: [AuthGuard],
        canActivateChild: [AuthGuard],
        component: LayoutComponent,
        resolve: {initialData: InitialDataResolver},
        data: {
            layout: 'empty',
            roles: ['user']
        },
        children: [
            {path: 'dashboard', loadChildren: () => import('app/modules/user/dashboard/user-analytics.module').then(m => m.UserAnalyticsModule)},
            {path: 'solarmanagement/:id', loadChildren: () => import('app/modules/admin/pages/userassigned/userassigned.module').then(m => m.UserassignedModule)},
            {path: 'settings', loadChildren: () => import('app/modules/dashboards/pages/settings/settingsuser.module').then(m => m.SettingsUserModule)},
            {path: '404-not-found', pathMatch: 'full', loadChildren: () => import('app/modules/admin/pages/error/error-404/error-404.module').then(m => m.Error404Module)},
            {path: '**', redirectTo: '404-not-found'},
        ]
    }
];

3. 修复登录后的动态跳转逻辑

在登录组件中,登录成功后根据用户角色跳转对应首页:

// auth-sign-in.component.ts
import { Component } from '@angular/core';
import { AuthService } from 'app/core/auth/auth.service';
import { Router } from '@angular/router';

@Component({
    selector: 'auth-sign-in',
    templateUrl: './sign-in.component.html'
})
export class AuthSignInComponent {
    constructor(
        private _authService: AuthService,
        private _router: Router
    ) {}

    onSignInSuccess(): void {
        const user = this._authService.currentUserValue;
        this._router.navigate([user.role === 'admin' ? '/admin/dashboard' : '/user/dashboard']);
    }
}

也可以通过守卫优化中转路由,实现自动跳转:

// signed-in-redirect.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from 'app/core/auth/auth.service';

@Injectable({providedIn: 'root'})
export class SignedInRedirectGuard implements CanActivate {
    constructor(
        private _authService: AuthService,
        private _router: Router
    ) {}

    canActivate(): boolean {
        const user = this._authService.currentUserValue;
        this._router.navigate([user.role === 'admin' ? '/admin/dashboard' : '/user/dashboard']);
        return false;
    }
}

// 路由中更新中转路由配置
{path: 'signed-in-redirect', pathMatch: 'full', canActivate: [SignedInRedirectGuard], component: LayoutComponent},

4. 清理冗余配置

  • 删除原有的admin-signed-in-redirect、user-signed-in-redirect路由
  • 移除重复的Auth路由配置(原代码末尾重复添加的公共Auth路由)
  • 确保Admin路由仅包含Admin专属页面,User路由仅包含User可访问页面

内容的提问来源于stack exchange,提问作者Jansen Su

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 01:40:33