Angular2 Auth Guard с http-запросом и наблюдаемыми

В настоящее время я реализую пример приложения angular2 с пружинной загрузкой в ​​качестве бэкэнда. У меня проблемы с механизмом внешнего интерфейса и наблюдаемыми.

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

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

Мой код в настоящее время выглядит следующим образом (я использую 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();
  }
}

Аут Сервис

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();
  }
}

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

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

1 ответ

Решение

+ Изменить

return subject.asObservable();

в

return subject.asObservable().first();

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

Другие вопросы по тегам