authentication - Angular2 auth guard 带有 http 请求和 observables

标签 authentication angular angular2-routing observable angular2-http

我目前正在实现一个以 spring boot 作为后端的 angular2 示例应用程序。我在前端身份验证保护机制和可观察对象方面遇到了一些问题。

我正在努力实现:

  1. 当有人进入一个 protected 路径时,auth guard 应该检查用户是否 已在 auth 服务变量中设置
  2. 如果未设置,则应发出 http 请求以检查 session 是否可用
  3. 服务方法应该返回一个 true/false 值(异步因为可能的 http 请求)
  4. 如果服务返回 false,auth guard 应该重定向到登录页面
  5. auth guard 应该返回 true/false 以便路由可以被激活或不被激活

我的代码目前看起来像这样(顺便说一句,我正在使用 RC5。):

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

问题是:守卫从不允许路由器组件激活,即使我已登录也是如此。

感谢您的帮助!

最佳答案

改变

return subject.asObservable();

return subject.asObservable().first();

路由器等待可观察对象完成。 first() 使其在第一个事件后完成。

关于authentication - Angular2 auth guard 带有 http 请求和 observables,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39053284/

相关文章:

mysql - 使用 LDAP (AD) 进行 MySQL 身份验证

Angular2获取激活的路由参数和父参数

angular - 具有模板驱动形式的 MatHorizo​​ntalStepper stepControl

Angular 2 Routing Guard CanActivateChild 与延迟加载模块路由

angular - 如何在 Angular 2的不同路线之间应用不同的动画

authentication - 尝试安装 SSL 时的 LetsEncrypt Web 服务器身份验证问题

javascript - 如何使用cookies构建登录页面?

reactjs - 当 session (存储的cookie)不可访问时如何保护 react 路由?

悬停时 Angular Material 按钮发生变化

angular - 服务中保存的数据在页面刷新或更改时丢失