2017-04-19 18 views
14

Tôi có một angular2 bảo vệ tích cực mà xử lý nếu người dùng không đăng nhập, chuyển hướng nó vào trang đăng nhập:Làm thế nào để áp dụng bảo vệ canActivate trên tất cả các tuyến đường?

import { Injectable } from "@angular/core"; 
import { CanActivate , ActivatedRouteSnapshot, RouterStateSnapshot, Router} from "@angular/router"; 
import {Observable} from "rxjs"; 
import {TokenService} from "./token.service"; 

@Injectable() 
export class AuthenticationGuard implements CanActivate { 

    constructor (
     private router : Router, 
     private token : TokenService 
    ) { } 

    /** 
    * Check if the user is logged in before calling http 
    * 
    * @param route 
    * @param state 
    * @returns {boolean} 
    */ 
    canActivate (
     route : ActivatedRouteSnapshot, 
     state : RouterStateSnapshot 
    ): Observable<boolean> | Promise<boolean> | boolean { 
     if(this.token.isLoggedIn()){ 
      return true; 
     } 
     this.router.navigate(['/login'],{ queryParams: { returnUrl: state.url }}); 
     return; 
    } 
} 

tôi phải thực hiện nó trên mỗi tuyến đường như:

const routes: Routes = [ 
    { path : '', component: UsersListComponent, canActivate:[AuthenticationGuard] }, 
    { path : 'add', component : AddComponent, canActivate:[AuthenticationGuard]}, 
    { path : ':id', component: UserShowComponent }, 
    { path : 'delete/:id', component : DeleteComponent, canActivate:[AuthenticationGuard] }, 
    { path : 'ban/:id', component : BanComponent, canActivate:[AuthenticationGuard] }, 
    { path : 'edit/:id', component : EditComponent, canActivate:[AuthenticationGuard] } 
]; 

Có bất kỳ cách nào tốt hơn để triển khai tùy chọn canActive mà không thêm nó vào mỗi đường dẫn.

Điều tôi muốn là thêm nó trên tuyến đường chính và nó sẽ áp dụng cho tất cả các tuyến đường khác. Tôi đã tìm kiếm rất nhiều, nhưng tôi không thể tìm thấy bất kỳ giải pháp hữu ích

Cảm ơn

Trả lời

44

Bạn có thể giới thiệu một tuyến đường componentless phụ huynh và áp dụng bảo vệ ở đó:

const routes: Routes = [ 
    {path: '', canActivate:[AuthenticationGuard], children: [ 
     { path : '', component: UsersListComponent }, 
     { path : 'add', component : AddComponent}, 
     { path : ':id', component: UserShowComponent }, 
     { path : 'delete/:id', component : DeleteComponent }, 
     { path : 'ban/:id', component : BanComponent }, 
     { path : 'edit/:id', component : EditComponent } 
    ]} 
]; 
+0

Cảm ơn, Nó hoạt động ngay bây giờ –

+0

Rất vui khi được nghe :) Cảm ơn bạn đã phản hồi. –

+2

@ GünterZöchbauer Tôi luôn đọc lời khuyên của bạn. Cảm ơn nhiều!! Nhưng trong trường hợp của tôi điều này không hoạt động. CanActive không hoạt động trong định tuyến giữa trẻ em. Tôi sử dụng canActivateChild. Nó hoạt động. – Smiranin

3

Tôi nghĩ rằng bạn nên thực hiện "tuyến trẻ "cho phép bạn có cha mẹ (ví dụ như" quản trị viên ") và con của anh ấy.

Sau đó, bạn có thể áp dụng một canactivate cho phụ huynh sẽ tự động hạn chế quyền truy cập vào tất cả các con của mình. Ví dụ nếu tôi muốn truy cập "admin/home", tôi sẽ cần phải đi qua "admin" được bảo vệ bởi canActivate. Thậm chí bạn có thể xác định một phụ huynh có đường dẫn trống "" nếu bạn muốn

0

Tôi đã xem ví dụ này khi tìm kiếm và bị phát hiện bởi ví dụ được đưa ra trong ví dụ.

Bạn cần đảm bảo rằng trình bảo vệ trả về true nếu bạn muốn hiển thị các tuyến con.

@Injectable() 
export class AuthenticationGuard implements CanActivate { 

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

    canActivate(
     route: ActivatedRouteSnapshot, 
     state: RouterStateSnapshot 
    ): Observable<boolean> | Promise<boolean> | boolean { 

     // Auth checking code here 

     // Make sure you return true here if you want to show child routes 
     return true; 
    } 
} 
0

Bạn cũng có thể đăng ký thay đổi tuyến đường của bộ định tuyến trong hàm ngOnInit của app.component và kiểm tra xác thực từ đó, ví dụ:

this.router.events.subscribe(event => { 
     if (event instanceof NavigationStart && !this.token.isLoggedIn()) { 
      this.router.navigate(['/login'],{ queryParams: { returnUrl: state.url}}); 
     } 
    }); 

Tôi thích cách này để thực hiện bất kỳ loại ứng dụng kiểm tra nào khi tuyến đường thay đổi.

Các vấn đề liên quan