Angular2 路由防护返回可观察<bool>,如何处理错误



我有一个路线守卫,如下

@Injectable()
export class AuthGuard implements CanActivate {
constructor(private router: Router, private authenticationSvc: AuthenticationService) { }
canActivate(): Observable<boolean> {
    return this.authenticationSvc.getAuthenticatedUser().map(
        r => {
            if (this.authenticationSvc.isAuthenticated()) {
                // logged in so return true
                return true;
            }
            this.router.navigateByUrl('/login');
            return false;
        })
}

问题是有时GetAuthentIcatedUser返回401,我有一个HTTP-Interceptor,可以处理401并重定向到登录页面。问题在于,此.MAP永远不会解决,因为HTTP请求会引发错误,并且Angular Router陷入了第一个路由请求,并且无法处理Interceptor的后续请求。我如何处理此错误并让可观察到的返回的解决方案解析为false并保持事物的移动?

  getAuthenticatedUser() {
         let getUserObservable = this.http.get(ApiUrl + 'security/getAuthenticatedUser')
            .map((res: any) => res.json())
            .share()
        //Get the result for the cache
        getUserObservable.subscribe(
            r => {
                if (r.success) {
                    this.authenticatedUser = r.result.user;
                }
            }); 
        //return the observable
        return getUserObservable;
  } 

和http-Intercepter

export class HttpInterceptor extends Http {
    authSvc: AuthenticationService;
    lastClicked: any = 0;
    constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private _router: Router, private injector: Injector) {
        super(backend, defaultOptions);
    }
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
    return this.intercept(super.request(url, options));
}
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
    return this.intercept(super.get(url, options));
}
post(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {
    return this.intercept(super.post(url, body, this.getRequestOptionArgs(options)));
}
put(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {
    return this.intercept(super.put(url, body, this.getRequestOptionArgs(options)));
}
delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
    return this.intercept(super.delete(url, options));
}
getRequestOptionArgs(options?: RequestOptionsArgs): RequestOptionsArgs {
    if (options == null) {
        options = new RequestOptions();
    }
    if (options.headers == null) {
        options.headers = new Headers();
    }
    options.headers.append('Content-Type', 'application/json');
    return options;
}
 intercept(observable: Observable<Response>): Observable<Response> {
    return observable.catch((err, source) => {
        //If we get a 401 from the api that means out FormsAuthenticationTicket has expired, clear the auth cookie and navigate back to terms page
        if (err.status == 401) {
            this._router.navigateByUrl('/login');
        }
        return Observable.throw(err);
    });
}

您可以捕获错误并返回Observable<bool>如下:

@Injectable()
export class AuthGuard implements CanActivate {
constructor(private router: Router, private authenticationSvc: AuthenticationService) { }
canActivate(): Observable<boolean> {
    return this.authenticationSvc.getAuthenticatedUser().map(
        r => {
            if (this.authenticationSvc.isAuthenticated()) {
                // logged in so return true
                return true;
            }
            this.router.navigateByUrl('/login');
            return false;
        })
        .catch((error: any) => {
            this.router.navigateByUrl('/login');
            return Observable.of(false);
        });
}

最新更新