2017-08-28 35 views
9

我面臨着以下問題:其通過AuthGuard服務保護個人節,當我瀏覽到它或者通過瀏覽器刷新加載兩次。第二次,如果我提供任何URL,它將刪除URL的查詢參數。這裏是我的應用程序路由器的配置:懶加載的子路徑負載兩次角

const routes: Routes = [ 
    { 
    path: 'search', 
    redirectTo: '', 
    pathMatch: 'full' 
    }, 
    { 
    path: '', 
    component: BookmarksComponent 
    }, 
    { 
    path: 'tagged/:tag', 
    component: TagComponent 
    }, 
    { 
    path: 'about', 
    component: AboutComponent 
    }, 
    { 
    path: 'personal', 
    loadChildren: 'app/personal/personal-bookmarks.module#PersonalBookmarksModule' 
    } 
]; 

@NgModule({ 
    imports: [RouterModule.forRoot(routes)], 
    exports: [RouterModule] 
}) 
export class AppRoutingModule {} 

和孩子路由器配置

@NgModule({ 
    imports: [RouterModule.forChild([ 
    { 
     path: '', 
     component: PersonalBookmarksComponent, 
     canActivate: [AuthGuard], 
     children: [ 
     { 
      path: '', 
      component: PersonalBookmarksListComponent 
     }, 
     { 
      path: 'new', 
      component: NewPersonalBookmarkFormComponent 
     }, 
     { 
      path: 'bookmarks/:id', 
      component: PersonalBookmarkDetailComponent 
     } 
     ] 
    } 

    ])], 
    exports: [RouterModule] 
}) 
export class PersonalBookmarksRoutingModule {} 

的AuthGuard服務(由此,如果它只返回true是相同的行爲):

@Injectable() 
export class AuthGuard implements CanActivate { 

    constructor(private keycloakService: KeycloakService) {} 

    canActivate() { 
    console.log('AuthGuard#canActivate called'); 

    if (this.keycloakService.isLoggedIn()) { 
     return true; 
    } else { 
     this.keycloakService.login(); 
    } 
    } 
} 

而且在導航欄模板:

<nav class="navbar navbar-light bg-faded" id="navbar"> 
    <a class="navbar-brand" [routerLink]="['']" routerLinkActive="active"> 
    <img src="assets/logo.png" width="35" height="35" class="d-inline-block align-top" alt=""> 
    Public Bookmarks 
    </a> 
    <ul class="nav navbar-nav"> 
    <li class="nav-item"> 
     <a class="nav-link" [routerLink]="['personal']" routerLinkActive="active">Personal list</a> 
    </li> 
    <li class="nav-item"> 
     <a class="nav-link" [routerLink]="['about']" routerLinkActive="active">About</a> 
    </li> 
    <li class="nav-item"> 
     <a class="nav-link" href="http://www.codingpedia.org/tags/#codingmarks" target="_blank">Blog</a> 
    </li> 
    <li *ngIf="isLoggedIn else notLoggedIn" class="nav-item"> 
     <a class="nav-link" (click)="logout()">Logout <i class="fa fa-lock"></i></a> 
    </li> 
    <ng-template #notLoggedIn> 
     <li *ngIf="!keycloakService.isLoggedIn()" class="nav-item"> 
     <a class="nav-link" (click)="login()">Login <i class="fa fa-unlock"></i></a> 
     </li> 
    </ng-template> 
    </ul> 
</nav> 

該項目可 on Github和錯誤行爲可以通過https://www.codingmarks.org/personal與登錄測試的用戶名/密碼 - [email protected]/Test_user1$

UPDATE 即使我刪除PersonalBookmarksComponent和移動AuthGuard到PersonalBookmarks模塊錯誤的行爲仍然存在......對於PersonalBookmarksModule的路線看起來類似以下內容:

const personalBookmarksRoutes: Routes = [ 
    { 
     path: 'search', 
     redirectTo: '', 
     pathMatch: 'full' 
    }, 
    { 
     path: '', 
     component: PersonalBookmarksListComponent, 
     canActivate: [AuthGuard], 
    }, 
    { 
     path: 'new', 
     component: NewPersonalBookmarkFormComponent 
    }, 
    { 
     path: 'bookmarks/:id', 
     component: PersonalBookmarkDetailComponent 
    } 

]; 

UPDATE2: 剝離掉的查詢參數之一是由於與Keycloak登錄時強制重定向。

public login(): Promise<any> { 
    let options: any; 
    options = {redirectUri: environment.HOST + 'personal'}; 
    return new Promise<any>((resolve, reject) => { 
    KeycloakService.auth.login(options) 
     .success(resolve) 
     .error(reject); 
    }); 
} 

正確

public login(): Promise<any> { 
    return new Promise<any>((resolve, reject) => { 
    KeycloakService.auth.login() 
     .success(resolve) 
     .error(reject); 
    }); 
} 
+0

您可以嘗試爲'BookmarksComponent'添加一個無空路徑 –

+0

我嘗試過,但得到相同的行爲,爲什麼它會有所幫助? – Adrian

回答

4

路線被加載兩次的原因是因爲你所指定的路由器路徑,當你去加載兩個組件導航到該' '路線。

改變路由器配置來

@NgModule({ 
    imports: [RouterModule.forChild([ 
    { 
     path: '', 
     //component: PersonalBookmarksComponent, //either remove this component line completely [best way is to remove this component deceleration] 
     canActivate: [AuthGuard], 
     children: [ 
     { 
      path: '', // or specify a different route to this better use a redirect option on path 
      component: PersonalBookmarksListComponent 
     }, 
     { 
      path: 'new', 
      component: NewPersonalBookmarkFormComponent 
     }, 
     { 
      path: 'bookmarks/:id', 
      component: PersonalBookmarkDetailComponent 
     } 
     ] 
    } 

    ])], 
    exports: [RouterModule] 
}) 
+0

PersonalBookmarksComponent只包含渲染「個人」子視圖的路由器插口......這也是官方路由器教程中採用的一種方法 - https://angular.io/generated/live-examples/router/eplnkr.html Still即使我將其更改爲非空(將孩子留空),或者將孩子組件更改爲非空,並將父路徑保留爲空,同樣的行爲仍然存在......我開始認爲它可能有一些用keycloak js adatper – Adrian

+0

@Adrian你可以在stackblitz中創建一個複製這個問題的小演示,因爲這應該已經起作用了 –

3

U可以執行以下兩個步驟:

  1. 移動authGuard到個人模塊路由,它還會提高你的性能,模塊不會在用戶未被認證的情況下加載。
  2. 刪除含有空路由器出口「PersonalBookmarksComponent」組分,而不是爲我們的組件的其餘部分直接提供的路由器。

我相信這個方法將解決您的問題。

警衛正在爲您的組件調用兩次,併爲您的子組件調用一次。

+0

Hey Chirag,那也沒有做 - 請參閱我的問題中的更新... – Adrian