5

В настоящее время я реализую приложение с угловым примером с пружинным ботинком в качестве backend. У меня возникают некоторые проблемы с механизмом защиты и наблюдениями frontend auth.Angular2 auth guard with http request and observables

Я пытаюсь достичь:

  1. , когда кто-то входит в охраняемую маршрутизировать аутентификации охранник должен проверить, если пользователь уже установлен в переменной аутентификации службы
  2. , если он не установлен, то HTTP- запрос должен быть выдан для проверки доступности сеанса
  3. метод службы должен возвращать значение true/false (асинхронно из-за возможного HTTP-запроса)
  4. , если служба возвращает false, auth guard должен перенаправить на страницу входа в систему
  5. аутентификации охранник должен возвращать истина/ложь так маршрут может либо быть активирована или нет

Мой код в настоящее время выглядит следующим образом (я использую RC5 кстати.):

Auth Guard

import {Injectable} from "@angular/core"; 
import {CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router} from "@angular/router"; 
import {Observable, Subject} from "rxjs/Rx"; 
import {AuthService} from "./auth.service"; 

@Injectable() 
export class AuthGuard implements CanActivate { 
    constructor(private authService: AuthService, private router: Router) {} 

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean { 
    var authenticated = this.authService.isAuthenticated(); 
    var subject = new Subject<boolean>(); 
    authenticated.subscribe(
     (res) => { 
      console.log("onNext guard: "+res); 
      if(!res && state.url !== '/signin') { 
      console.log("redirecting to signin") 
      this.router.navigate(['/signin']); 
      } 
      subject.next(res); 
     }); 
    return subject.asObservable(); 
    } 
} 

Auth служба

import {Injectable} from "@angular/core"; 
import {User} from "./user.interface"; 
import {Router} from "@angular/router"; 
import {Http, Response, Headers} from "@angular/http"; 
import {environment} from "../environments/environment"; 
import {Observable, Observer, Subject} from "rxjs/Rx"; 

@Injectable() 
export class AuthService { 
    private authenticatedUser : User; 
    constructor(private router: Router, private http: Http) {} 

    signupUser(user: User) { 
    } 


    logout() { 
    //do logout stuff 
    this.router.navigate(['/signin']); 
    } 

    isAuthenticated() : Observable<boolean> { 
    var subject = new Subject<boolean>(); 
    if (this.authenticatedUser) { 
     subject.next(true); 
    } else { 
     this.http.get(environment.baseUrl + '/user') 
     .map((res : Response) => res.json()) 
     .subscribe(res => { 
      console.log("next: returning true"); 
      this.authenticatedUser = User.ofJson(res); 
      subject.next(true); 
     }, (res) => { 
      console.log("next: returning false"); 
      subject.next(false); 
     }); 
    } 
    return subject.asObservable(); 
    } 
} 

проблема заключается в следующем: защита никогда не активирует компонент маршрутизатора, даже если я вошел в систему.

Спасибо за помощь!

+0

В чем проблема? –

+0

см. Edit, компонент маршрутизатора никогда не активируется, даже когда я успешно вошел в систему. Если я не использую никаких наблюдаемых, он отлично работает, но я не могу использовать HTTP-запросы, поэтому это не вариант для меня. – Tim

ответ

7

Изменить

return subject.asObservable(); 

в

return subject.asObservable().first(); 

Маршрутизатор ждет наблюдаемым для завершения. first() делает это после первого события.

+0

Спасибо, что решает часть проблемы. Что происходит сейчас, так это то, что когда я нажимаю на защищенный маршрут, он всегда препятствует активации маршрута и выводит сообщение журнала. Но когда я ввожу действительные учетные данные авторизации на экране входа в систему, а сервер отвечает с 200 OK, я до сих пор не могу получить доступ к защищенному маршруту. Когда я нажимаю f5 и обновляю страницу, я внезапно могу получить доступ к защищенному маршруту. Вероятно, это связано с переменной authenticatedUser в классе службы, где я храню объект пользователя, но я не уверен, почему, какие-либо идеи? – Tim

+1

Вы можете попробовать использовать 'BehaviorSubject' вместо' Subject' в 'isAuthenticated()'. В настоящее время, если 'this.authenticatedUser' является' true', вы испускаете 'true', но на данный момент абонента еще нет. Эта часть кода выполняется синхронно, и 'true' испускается до того, как будет выполняться функция return subject.asObservable()', и вызывающий объект isAuthenticated() 'не получит это событие. –

+2

Мне пришлось использовать комбинацию BehavorSubject (Service) и ReplaySubject (guard), но теперь он работает как ожидается. Благодаря! – Tim

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

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