この 例のプロジェクト では、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) に渡す方法がわかりません。だから私はこのような何かを達成したいと思います(例えば、私は2つの役割を持っています:管理者と従業員):
{ 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トークンに保存されているユーザーロールを読み取るヘルパーです。上記のアイデアのような何かをする方法はありますか?
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
このような役割を持つルートのdata
パラメーターを設定できます
const appRoutes: Routes = [
{
path: 'account/super-secure',
component: SuperSecureComponent,
canActivate: [RoleGuard],
data: { roles: ['super-admin', 'admin'] }
}];
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);
}
これは、すべての役割にガードを作成する代わりに、別の方法で行うことができると思います。必要なコードが少なく、問題を非常にうまく処理できるので、実際にこのルーティングを使用します。
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;
}
もちろん、プライベートプロパティを避ける方が良いでしょうし、できますが、私がどうやってそれを行ったかを思い出せません。
しかし、私の目的のために、私は別の方法でそれをやり直しました。このアプローチの大きな欠点は、ロールベースのガードの場合、異なるロールを持つすべてのユーザーが、手動ではなくコンポーネントで自動的にレンダリングする場合、すべてのルートを見ることができるということです。