2016-12-19 4 views
5

Я создаю приложение, в котором нет доступа для не прошедших проверку пользователей.Angular2: Global Guard (пользователь должен войти в систему всегда)

Я написал LoggedInGuard, но теперь я должен добавить canActivate: [LoggedInGuard] к каждый маршрут внутри моей конфигурации маршрутизатора (за исключением LoginComponent).

Есть ли лучший способ заставить это работать?


Мой макет файл/модуль выглядит следующим образом:

app/ 
    AppModule 
    AppRoutingModule 
    AppComponent 

    authentication/ 
    AuthenticationModule 
    AuthenticationRoutingModule 
    LoginComponent 

    contacts/ 
    ContactsModule 
    ContactsRoutingModule 
    ContactListComponent 

    users/ 
    UsersModule 
    UsersRoutingModule 
    UserEditComponent 

    ... 

Может быть, можно создать два отдельных пространства маршрутизации (один для входа, один для остальной части приложения) и применить охранник только до остальное приложение часть?


Надеюсь, что есть простое решение.

Заранее благодарен!

+1

если мой ответ не имеет смысла, дайте мне знать человека. Я действительно думаю, что это должно помочь вам, основываясь на ваших обстоятельствах. в основном я говорю, что вы можете сделать один маршрут с охраной.Затем сделайте все остальные страницы сайта, которые должны быть защищены ребенком родительского маршрута с помощью Guard. – wuno

ответ

6

Я думаю, что я делаю это гораздо логичнее. Думаю, это мнение. Я отделяю свое приложение от secured pages и public pages. Я использую шаблоны для каждого набора. Итак, public component и secure component затем положите guard на secure template.

Убедитесь, что вы добавляете [Guard] на весь маршрут, который нуждается в защите.

Так что, когда я обеспечить маршрут я добавляю родителей app.routing.ts

const APP_ROUTES: Routes = [ 
    { path: '', redirectTo: '/home', pathMatch: 'full', }, 
    { path: '', component: PublicComponent, data: { title: 'Public Views' }, children: PUBLIC_ROUTES }, 
    { path: '', component: SecureComponent, canActivate: [Guard], data: { title: 'Secure Views' }, children: SECURE_ROUTES } 
]; 



export const routing = RouterModule.forRoot(APP_ROUTES); 

Убедитесь, что эта линия Замечено,

{ path: '', component: SecureComponent, canActivate: [Guard], data: { title: 'Secure Views' }, children: SECURE_ROUTES } 

Так я создаю 2 раскладок

/государственные/все общественные компоненты

/public/public.routes.ts

/безопасный/все безопасные компоненты

/secure/secure.routes.ts

Безопасные маршруты

Примечание что эти маршруты не нужны сейчас Guard, потому что они обрабатываются родителем шаблона.

export const SECURE_ROUTES: Routes = [ 
    { path: '', redirectTo: 'overview', pathMatch: 'full' }, 
    { path: 'items', component: ItemsComponent }, 
    { path: 'overview', component: OverviewComponent }, 
    { path: 'profile', component: ProfileComponent }, 
]; 

Основные маршруты в app.routing.ц

const APP_ROUTES: Routes = [ 
    { path: '', redirectTo: '/home', pathMatch: 'full', }, 
    { path: '', component: PublicComponent, data: { title: 'Public Views' }, children: PUBLIC_ROUTES }, 
    { path: '', component: SecureComponent, canActivate: [Guard], data: { title: 'Secure Views' }, children: SECURE_ROUTES } 
]; 

export const routing = RouterModule.forRoot(APP_ROUTES); 

И в директории/макеты, которые я создаю макет, который

/layouts/secure.component.ts

/layouts/secure.component.html

/layouts/public.component.ts

/layouts/public.component.html

Все проходит через макет public или secure и [Guard] находится на безопасном.

Затем я обрабатываю аутентификацию с помощью токена в локальном хранилище.

@Injectable() 
export class Guard implements CanActivate { 

    constructor(protected router: Router, protected auth: Auth) {} 

    canActivate() { 
     if (localStorage.getItem('access_token')) { 
      // logged in so return true 
      return true; 
     } 
     // not logged in so redirect to login page 
     this.router.navigate(['/home']); 
     return false; 
    } 
} 

После того, как я установил мое приложение вверх, как это я положил все свои маршруты, которые должны быть безопасными в защищенном каталоге и маршрутах общего пользования в общественных местах. Затем я создаю их маршруты в файле public.routes.ts или файле secure.routes.ts, который находится в соответствующем каталоге.

+0

Интересный ... ваш путь для безопасного и общедоступного компонента ok или вы имели в виду '{path: 'public', component: PublicComponent' и' {path: 'secure', component: SecureComponent'? –

+1

Ну, путь может быть тем, что вы хотите сделать. Я использую их так, как они есть. Я могу управлять маршрутами с детских маршрутов. – wuno

+0

Я пропустил SecureComponent и PublicComponent. –

4

Я смог предоставить набор глобальных охранников, которые охватывают несколько модулей, перемещая охранники в приемник событий маршрутизатора.

Чтобы сделать пожар слушателя событий для всех запросов, я вставил его в AppComponent.

Обратите внимание, что в обоих примерах, приведенных ниже, вы по-прежнему можете добавлять пользовательские охранники для отдельных маршрутов, и они все равно будут работать.

Без гвардии

Вы можете удалить использование охранников и вместо того, чтобы реализовать логику непосредственно у слушателя событий.

import { Component, OnInit } from '@angular/core'; 
import { Router, RoutesRecognized } from '@angular/router'; 
import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/operator/filter'; 

// I use a service to keep track of the authentication ticket. 
// Replace this with whatever mechanism you use. 
import { AuthenticationService } from './_services/index'; 

@Component({ 
    selector: 'app-root', 
    templateUrl: './app.component.html', 
    styleUrls: ['./app.component.css'] 
}) 
export class AppComponent implements OnInit { 
    constructor(
     private router: Router, 
     private authService: AuthenticationService 
) {} 

    ngOnInit() { 
    this.router.events 
    .filter(event => event instanceof RoutesRecognized) 
    .subscribe((event: RoutesRecognized) => { 
     const url = event.urlAfterRedirects; 

     // Public URLs don't need any kind of authorization. 
     if (url === '/public' || url.startsWith('/public/') || url.startsWith('/public?')) { 
     return; 
     } 

     // Everything else must be authenticated. 
     if (!this.authService.isAuthenticated()) { 
     // Allow for the login page to redirect back to the originally 
     // requested page. 
     this.router.navigate(['/public/login'], { queryParams: { returnUrl: state.url } }); 
     } 
    }); 
    } 
} 

просит, которые передаются в любой суб-странице /public будет проходить через независимо, но и любой другой запрос должен иметь аутентификации, или он будет перенаправлять на /public/login.

Позаботьтесь о том, чтобы страница перенаправления не находилась в защищенной области, иначе маршрутизатор будет вводить бесконечный цикл.

С гвардейской

Реализация ниже показывает, как я повторно существующих охранников. Это только в том случае, если вам нужно сохранить их, или если он сделает ваш код более чистым.

import { Component, OnInit } from '@angular/core'; 
import { Router, ActivatedRoute, RoutesRecognized, CanActivate } from '@angular/router'; 
import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/operator/filter'; 
import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/mergeMap'; 

// Reused guards. 
import { AdminGuard, AuthGuard } from './_guards/index'; 


@Component({ 
    selector: 'app-root', 
    templateUrl: './app.component.html', 
    styleUrls: ['./app.component.css'] 
}) 
export class AppComponent implements OnInit { 

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

    ngOnInit() { 
    this.router.events 
    .filter(event => event instanceof RoutesRecognized) 
    .subscribe((event: RoutesRecognized) => { 
     // Public pages don't require authentication. 
     if (this.isSubPage(event, '/public')) { 
     return; 
     } 

     // All other requests MUST be done through an 
     // authenticated connection. The guard performs 
     // the redirection for us. 
     if (!this.callCanActivate(event, this.authGuard)) { 
     return; 
     } 

     // Administration pages require additional restrictions. 
     // The guard performs the redirection for us. 
     if (this.isSubPage(event, '/admin')) { 
     if (!this.callCanActivate(event, this.adminGuard)) { 
      return; 
     } 
     } 
    }); 
    } 

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

    isSubPage(event: RoutesRecognized, parent: string) { 
    const url = event.urlAfterRedirects; 
    return (url === parent 
     || url.startsWith(parent + '/') 
     || url.startsWith(parent + '?')); 
    } 
} 

В этом примере такого же, как показано выше, но с дополнительной защитой для /admin области, который гарантирует, что пользователь также имеет право администратора.

+0

Пока работает «с защитой», это в настоящее время небезопасно, потому что дочерние маршруты, добавленные через 'forChild', добавляются как братья и сестры к маршрутам' forRoot', таким образом, не в пределах иерархии и не будут запускать охрану. –

 Смежные вопросы

  • Нет связанных вопросов^_^