具有http请求和可观察量的Angular2 auth防护

时间:2016-08-20 10:50:59

标签: authentication angular angular2-routing observable angular2-http

我目前正在使用spring boot作为后端实现angular2示例应用程序。我在前端保护机制和可观察性方面遇到了一些问题。

我正在努力实现:

  1. 当有人进入受保护路线时,认证警卫应检查用户是否 已在auth服务变量中设置
  2. 如果未设置,则应发出http请求以检查会话是否可用
  3. service方法应返回true / false值(由于可能的http请求而异步)
  4. 如果服务返回false,则auth guard应重定向到登录页面
  5. auth guard应返回true / false,以便路由可以激活或不激活
  6. 我的代码目前看起来像这样(我正在使用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 个答案:

答案 0 :(得分:9)

更改

return subject.asObservable();

return subject.asObservable().first();

路由器等待observable完成。 first()在第一次活动结束后完成。