Angular2路由可以使用用户角色参数激活和身份验证(JWT)

Angular2 routing canActivate and AuthGuard (JWT) with user role parameter

本文关键字:身份验证 JWT 激活 参数 可以使 路由 用户 角色 Angular2      更新时间:2023-09-26

在这个带有 JWT 身份验证的示例项目中,我们了解了如何仅允许经过身份验证的用户访问某些路由:

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

我想更进一步,并指出哪个用户角色具有"访问权限"来路由 - 但我不知道如何将参数传递给canActivate AuthGuard(src)。所以我想实现这样的事情(例如我有两个角色:管理员和员工):

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

我的AuthGuard看起来像这样(其中userRole(= Admin or Employee or 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令牌中的用户角色的帮助程序。有没有办法做类似上面的想法?

你可以像这样设置路由的data参数

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

然后在RoleGuard canActivate有这个:

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

我认为这可能是另一种方式,而不是为每个角色创建警卫。我实际上会接受这种溃败,因为它需要更少的代码并且很好地处理了问题。

CanActivate的签名不允许你像你想要的那样传递userRole。 https://github.com/angular/angular/blob/2.0.0-rc.4/modules/%40angular/router/src/interfaces.ts#L54

最好为每个用户角色案例执行单独的类。这也是官方文档中的指导:https://angular.io/docs/ts/latest/api/router/index/CanActivate-interface.html

注意:适用于角度 RC.4 <</strong>

@KamilKie乌切夫斯基,@NikolayRusev,

  1. 在路由中添加了带有路由数组的其他数据:

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

当然,最好避免私有财产,你可以,但我不记得我到底是怎么做到的。

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

  1. 您可以扩展router-outlet
    • http://www.captaincodeman.com/2016/03/31/angular2-route-security/
    • https://medium.com/@blacksonic86/authentication-in-angular-2-958052c64492#.cxgoan9go