简体   繁体   English

Angular2路线守卫返回Observable <bool> ,如何处理错误

[英]Angular2 route guard returning Observable<bool>, how to handle errors

I have a route guard like below 我有一个像下面这样的路线保护

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

The issue is that sometimes getAuthenticatedUser returns a 401, and I have an http-interceptor that handles the 401 and redirect to the login page. 问题是有时getAuthenticatedUser返回401,我有一个http拦截器来处理401并重定向到登录页面。 The issue is that this .map never resolves because the http request throws an error, and the angular router gets stuck on this first routing request and can't handle the subsequent request from the interceptor. 问题是这个.map永远不会解析,因为http请求会抛出错误,并且角度路由器会卡在第一个路由请求上,无法处理来自拦截器的后续请求。 How can I handle this error and have the Observable returned resolve to false and keep things moving? 如何处理此错误并将Observable返回的解析为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;
  } 

and http-intercepter below 和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);
    });
}

You can catch errors and return Observable<bool> as follows: 您可以捕获错误并返回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);
        });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM