2017-10-18 17 views
1

最近、角のあるルートガードがついた。 CanActiveは、ページがロードされたときに一度だけ実行され、ガードされたルート内のルート変更では実行されません。私はこれが変更のたびに実行されていたので変更されたと思います。私がフォーラムで読んだことから、私はCanActivateChildを使うべきです。問題は、私たちのアプリケーションがいくつかのルート子孫を持ついくつかのモジュールで構成されていることです。ルートモジュールでCanActivateChildを使用すると、ルートを変更するときに何度か呼び出されます。角度:各ルート変更時にcanActivateを実行する

AppModuleの場合、遅延ロードされた子モジュールは単に「ブラックボックス」である必要があるため、これらのモジュールをすべて保護する必要があるため、それぞれの子にガードを割り当てるのは馬鹿です。

export const routes: Routes = [ 
    { 
    path: '404', 
    component: NotFoundComponent 
    }, 
    { 
    path: '', 
    canActivate: [AuthGuard], 
    component: FullLayoutComponent, 
    data: { 
     title: 'Home' 
    }, 
    children: [ 
     { 
     path: 'administration', 
     loadChildren: './administration/administration.module#AdministrationModule' 
     }, 
     { 
     path: 'settings', 
     loadChildren: './settings/settings.module#SettingsModule' 
     } 
    ] 
    }, 
    { 
    path: '', 
    loadChildren: './account/account.module#AccountModule' 
    }, 
    { 
    path: '**', 
    redirectTo: '404' 
    } 
]; 

この問題を解決する方法はありますか?または、これはセキュリティに関して「問題ではない」と考えられますか?

ありがとうございました。

答えて

0

同じ問題に直面していましたが、私が問題で見つけたのは、Github上で、このような振る舞いが「設計通りの」Angular devs文を使っていくつかのクローズドな問題でした。

constructor(
    private router: Router, 
    private route: ActivatedRoute, 
    private authGuard: AuthGuard, 
) {} 

ngOnInit() { 
    this.router.events 
    .subscribe(event => { 
     if (event instanceof RoutesRecognized) { 
     this.guardRoute(event); 
     } 
    })); 
} 

private guardRoute(event: RoutesRecognized): void { 
    if (this.isPublic(event)) { 
    return; 
    } 

    if (!this.callCanActivate(event, this.authGuard)) { 
    return; 
    } 
} 

private callCanActivate(event: RoutesRecognized, guard: CanActivate) { 
    return guard.canActivate(this.route.snapshot, event.state); 
} 

private isPublic(event: RoutesRecognized) { 
    return event.state.root.firstChild.data.isPublic; 
} 

AuthGuardはかなり標準です:

@Injectable() 
export class AuthGuard implements CanActivate{ 

    constructor(private auth: AuthService, private router: Router) { } 

    canActivate(): Promise<boolean> { 
    return this.auth.isLoggedInPromise() 
     .then(isLoggedIn => { 
     if (!isLoggedIn) { 
      this.router.navigate(["/login"]); 
     } 
     return isLoggedIn; 
     }); 
    } 
    } 

とパブリックルートを設定する必要があり

は、だから私はapp.componentにナビゲーションイベントにサブスクライブし、そこAuthGuardチェックを発射されてやってしまったものを

{ 
    path: "login", 
    component: LoginComponent, 
    data: { isPublic: true } 
} 

このような実装のプラスは次のとおりです。物はデフォルトで保護されており、公共のルートを明示的に設定する必要があります。これにより、保護されていないルートを残す可能性が減ります。また、これをいくつかの種類のサービスにリファクタリングし、複数のアプリで使用できるようにします。

this answerに触発されています。

+0

ええ、私はexatly同じを見つけました。 "意図的に"。私はこれまでのところあなたの答えを最高の解決策として見つけました。ありがとう! –

関連する問題