2016-10-14 1 views
3

У меня есть приложение с угловым 2, настроенное с защитой маршрута, которая в настоящее время проверяет, вошел ли пользователь в систему или нет. Это работает нормально, но теперь я пытаюсь настроить еще один охранник маршрута, который не только проверяет, что пользователь вошел в систему, но и независимо от того, являются ли они администратором.Защитные ограждения AngularFire2 по ролям пользователей

Это то, что у меня есть на данный момент:

import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router'; 
import { Injectable } from '@angular/core'; 
import { Observable } from 'rxjs/Rx'; 
import { AngularFire } from 'angularfire2'; 
import { AuthService } from './auth.service'; 
import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/first'; 
import 'rxjs/add/operator/take'; 

@Injectable() 
export class AdminGuard implements CanActivate { 

    constructor(
    private af: AngularFire, 
    private authService: AuthService, 
    private router: Router 
) { 

    } 

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

    let redirectURL:string = state.url; 

    return this.af.auth.map((auth) => { 
     if (auth == null) { 
     this.authService.redirectURL = redirectURL; 
     this.router.navigate(['/login']); 
     return false; 
     } else { 

     return this.af.database.object('roles/admins/'+auth.uid, { preserveSnapshot: true }) 
      .take(1) 
      .subscribe(res => { 
      if (res.val()) { 
       console.log('is admin, return true'); 
       return true; 
      } else { 
       console.log('access denied'); 
       this.router.navigate(['/']); 
       return false; 
      } 
      }); 

     } 
    }).first(); 

    } 

} 

В тот момент, когда я пытаюсь идти к маршруту, который защищен этим охранником, я получаю console.log выход 'is admin, return true', но ничего не происходит. Новый маршрут не отображается, и приложение остается на текущей странице.

Может ли кто-нибудь сказать мне, где я ошибаюсь, пожалуйста? Спасибо за любую помощь.

+0

Попробуйте без ['first()'] (http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-first). У вас также есть вложенные подписки, возможно, вы можете реорганизовать код ... – Sasxa

+0

Удаление first() не помогло. Как бы вы перешли к рефакторингу кода? –

ответ

1

Понял работать с этим в конце:

let redirectURL:string = state.url; 

return this.af.auth 
    .flatMap(auth => { 
    if (auth == null) { 
     return new Promise(resolve => { resolve({}) }); 
    } else { 
     return this.af.database.object(`roles/admins/${auth.uid}`); 
    } 
    }) 
    .map(data => { 
    if (data.$value) { 
     return data.$value; 
    } else { 
     // User doesn't have permission 
     this.authService.redirectURL = redirectURL; 
     this.router.navigate(['/404']); 
     return false; 
    } 
    }) 
    .first(); 

Все еще нуждается в тестировании, но я его быстро закончил, прежде чем покинуть офис. Кажется, сейчас работает нормально :)