4

如果用户登录,我有一个“CanActivate”检查我的网络服务。

“CanActivate”返回 Observable。唯一担心的是,我需要恢复这个布尔值的值,以便能够在用户连接或不连接的情况下调整我的视图,而无需重做第二个请求......

canActivate(): Observable<boolean>|boolean {
    return this.connected();
  }
public connected() : Observable<boolean>{
    return this.http.get(this.connectedUrl,{ withCredentials: true })
      .map(this.extractBoolean)
      .catch(this.handleError);
  }

谢谢您的帮助

4

2 回答 2

1

如果您想在后端发出请求以确保用户已连接时保存一些数据,而不是在 中发出 HTTP 请求guard,请创建一个service执行该请求的是否要保存请求)。

也就是说,在你service的单例中,你可以简单地map调用(结果为一个Observable)并将值保存在你的service.

例如 :

@Injectable()
export class SomeService {
  private userData: IUserData;

  constructor(private http: Http) { }

  getUserDataIfConnected() {
    this.http.get('http://some-url')
      .map((res: Response) => res.json() as IUserData)
      .map(userData => this.userData = userData)
  }
}

然后在你的后卫:

canActivate(): Observable<boolean> {
  return this.someService.getUserDataIfConnected()
    // if there was no error, we don't care about the result, just return true : The user is connected
    .mapTo(true)
    // if the user wasn't logged, your backend shoud return an HTTP error code in the header
    // and angular HTTP service will throw an error
    .catch(err => return Observable.of(false))
}

它不必比这更复杂:)

于 2017-05-11T08:48:28.623 回答
1

我有一个类似的问题,并使用身份验证服务解决了它,我改为使用 BehaviorSubject 来跟踪成员身份验证状态:

public member: Subject<Member> = new Subject<Member>();

private _cachedMember: Member;
private _member$: BehaviorSubject<Member>;

constructor(private _http: Http, private _router: Router) {         
}

get member$(): Observable<Member> {     
    if (!this._cachedMember) {          
        this.getAuthorizedMember().subscribe();
    }
    return this._member$.asObservable();
}

private getAuthorizedMember(): Observable<Member> {
     // call your auth API and set _cachedMember accordingly:
     this._cachedMember = member;
     this._member$.next(this._cachedMember);
}

我的 auth.guard.ts canActivate 实现:

canActivate(): Observable<boolean> | boolean {

        return this._authService.member$.map(member => {
            if (member) return true;
            else {
                // Set entry url
                var currentUrl: URL = new URL(this._document.location.href);
                this._authService.entryUrl = currentUrl.pathname;

                this._router.navigate(['/']);
                return false;
            }
        });

}

else 语句保存了 url 请求,因此会员登录后被正确重定向。

然后,如果 _cachedMember 为空,您只需要调用您的身份验证 API。请记住在注销时将 _cachedMember 设置为 null 并通知主题。

logout() {
    this._cachedMember = null;
    this._member$.next(this._cachedMember );
}

[编辑] 我发现早期解决方案存在问题。将授权机制包装在可观察对象中是一个好主意,如果 _member$ 主题已分配,则进行空检查。如果直接导航到受保护的路线,则初始状态是有效的!

于 2017-05-11T08:43:07.650 回答