[英]Angular2 routing canActivate and AuthGuard (JWT) with user role parameter
In this exaple project with JWT authentication we se how to allow only authenticated users to some route: 在这个使用JWT身份验证的exaple项目中 ,我们将了解如何仅允许经过身份验证的用户访问某些路由:
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 },
];
I would like make step further and also indicate what user role have 'access' to route - but I don't know how to pass argument to canActivate AuthGuard (src) . 我想更进一步,并指出用户角色有什么“访问”路由 - 但我不知道如何将参数传递给canActivate AuthGuard(src) 。 So I would like to achieve something like this (for instance I have two roles: Admin and Employee):
所以我想实现这样的目标(例如我有两个角色:Admin和Employee):
{ path: 'home', component: Home, canActivate: [AuthGuard] },
{ path: 'users', component: AdminUsers, canActivate: [AuthGuard('Admin')] },
{ path: 'users', component: Employees, canActivate: [AuthGuard('Employee')] },
Where my AuthGuard could look something like this (where userRole(= Admin or Employee or null) is passed parameter to AuthGuard): 我的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;
}
}
where JWT.user.role is helper which read user role stored in JWT token. 其中JWT.user.role是帮助程序,它读取存储在JWT令牌中的用户角色。 Is there a way to do something similar like above idea?
有没有办法像上面的想法做类似的事情?
You can set the data
parameter of the route with the role like this 您可以使用如下角色设置路径的
data
参数
const appRoutes: Routes = [ { path: 'account/super-secure', component: SuperSecureComponent, canActivate: [RoleGuard], data: { roles: ['super-admin', 'admin'] } }];
and then have this in canActivate
of RoleGuard
: 然后在
canActivate
of 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); }
I think this could be another way of doing it instead of creating guard for every role. 我认为这可能是另一种方式,而不是为每个角色创造防范。 I would actually take this rout since it requires less code and handles the problem very nicely.
我实际上会采取这种溃败,因为它需要更少的代码并且非常好地处理问题。
The signature for CanActivate
won't allow you to pass a userRole
like you want to. CanActivate
的签名不允许您按照CanActivate
意愿传递userRole
。 https://github.com/angular/angular/blob/2.0.0-rc.4/modules/%40angular/router/src/interfaces.ts#L54 https://github.com/angular/angular/blob/2.0.0-rc.4/modules/%40angular/router/src/interfaces.ts#L54
It's probably best to do separate classes for each of your user role cases. 最好为每个用户角色案例分别执行类。 That's the guidance in the official docs too: https://angular.io/docs/ts/latest/api/router/index/CanActivate-interface.html
这也是官方文档中的指导: https : //angular.io/docs/ts/latest/api/router/index/CanActivate-interface.html
NOTE : applicable for angular-rc.4 < 注意 :适用于angular-rc.4 <
@KamilKiełczewski, @NikolayRusev, @KamilKiełczewski,@ NikolayRusev,
added in route additional data with array of routes: 添加路由附加数据与路由数组:
...
{
path: "customers",
component: CustomersCmp,
data: { roles: ["admin"] }
},
...
and in CanActivate you can get path
from first parameter, search the same path in route config and get your described roles from data: 在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;
}
Of course it would be better to avoid private properties, and you can, but I cannot remember how I exactly done it. 当然最好避开私有财产,你可以,但我不记得我是怎么做到的。
But for my porposes I redid it in different way. 但是对于我的作品,我以不同的方式重新制作它。 The huge disadvantage of this approach, I mean for role based guard, is that every user with different roles can see all of the routes if you render them in a component automatically not manually.
这种方法的巨大缺点,我的意思是基于角色的防护,是每个具有不同角色的用户都可以看到所有路由,如果您在一个组件中自动而不是手动渲染它们。
router-outlet
router-outlet
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.