首页 文章

Angular2路由可以使用用户角色参数激活和使用AuthGuard(JWT)

提问于
浏览
38

在具有JWT身份验证的exaple project中,我们将了解如何仅允许经过身份验证的用户访问某些路由:

import { RouterConfig } from '@angular/router';
import { Home } from './home';
import { Login } from './login';
import { Signup } from './signup';
import { AuthGuard } from './common/auth.guard';

export const routes: RouterConfig = [
  { path: '',       component:  Login },
  { path: 'login',  component: Login },
  { path: 'signup', component: Signup },
  { path: 'home',   component: Home, canActivate: [AuthGuard] },
  { path: '**',     component: Login },
];

我想更进一步,并指出用户角色'access'要路由 - 但我不知道如何将参数传递给canActivate AuthGuard (src) . 所以我想实现这样的目标(例如我有两个角色:Admin和Employee):

{ path: 'home',   component: Home, canActivate: [AuthGuard] },
  { path: 'users',   component: AdminUsers, canActivate: [AuthGuard('Admin')] },
  { path: 'users',   component: Employees, canActivate: [AuthGuard('Employee')] },

我的AuthGuard看起来像这样(userRole(= Admin或Employee或null)将参数传递给AuthGuard):

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private router: Router) {}

  canActivate(userRole) {
    if (!userRole || JWT.user().role == userRole) {
      return true;
    }

    this.router.navigate(['/login']);
    return false;
  }
}

其中JWT.user.role是帮助程序,它读取存储在JWT令牌中的用户角色 . 有没有办法像上面的想法那样做类似的事情?

3 回答

  • 5
  • 2

    您可以使用如下角色设置路径的 data 参数

    const appRoutes: Routes = [
    { 
      path: 'account/super-secure', 
      component: SuperSecureComponent, 
      canActivate: [RoleGuard], 
      data: { roles: ['super-admin', 'admin'] } 
    }];
    

    然后在 canActivate RoleGuard 中有这个:

    canActivate(route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot): boolean {
    
        let roles = route.data["roles"] as Array<string>;
        return (roles == null || roles.indexOf("the-logged-user-role") != -1);
    }
    

    我认为这可能是另一种方式,而不是为每个角色创造防范 . 我实际上会采取这种溃败,因为它需要更少的代码并且非常好地处理问题 .

  • 76

    NOTE :适用于 angular-rc.4 <

    @KamilKiełczewski,@ NikolayRusev,

    • 添加路由附加数据与路由数组:
    ...
    {
        path: "customers",
        component: CustomersCmp,
        data: { roles: ["admin"] }
    },
    ...
    

    在CanActivate中,您可以从第一个参数获取 path ,在路径配置中搜索相同的路径,并从数据中获取您描述的角色:

    public canActivate(route: ActivatedRouteSnapshot): boolean {
        let path = route._urlSegment.pathsWithParams[0].path;
        let roles;
    
        if (route._routeConfig.path == path) {
            roles = route._routeConfig.data.roles
        } else {
            roles = route._routeConfig.children.find(_route => _route.path == path).data.roles;
        }
    
        if (...) {
            return true;
        }
    
        return false;
    }
    

    当然最好避开私有 property ,你可以,但我不记得我是怎么做到的 .

    但是对于我的作品,我以不同的方式重新制作它 . 这种方法的巨大缺点,我的意思是基于角色的防护,是每个具有不同角色的用户都可以看到所有路由,如果您在一个组件中自动而不是手动渲染它们 .

相关问题