【问题标题】:Handle HttpErrorResponse from an Observable that doesn't return a boolean inside a canActivate()在 canActivate() 中处理不返回布尔值的 Observable 的 HttpErrorResponse
【发布时间】:2019-06-24 11:58:23
【问题描述】:

我正在尝试创建一个 canActivate() 函数,它将:

return false;
this.router.navigateByUrl('/login'); 

当状态码 401 来自 Observable 时,即当 HttpErrorResponse 出现时。

===============================================

这是我的服务:

currentUser(token): Observable<any> {
    const url = `${this.BACKEND_URL}/status`;
    const httpOptions = {
        headers: new HttpHeaders({
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${token}`
        })
    };
    return this.http.post(url, {'token': token}, httpOptions);
}

响应数据是 Json blob,可以是 401200 状态码,这是 Python 代码:

post_data = request.get_json()
post_token = post_data.get('token')

resp = User.decode_auth_token(post_token)
if not isinstance(resp, str):
    user = User.query.filter_by(id=resp).first()
    response_object = {
        'status': 'success',
        'data': {
            'user_id': user.id,
            'email': user.email.lower(),
            'first_name': user.first_name,
            'last_name': user.last_name,
            'admin': user.admin,
            'registered_on': user.registered_on
        }
    }
    return make_response(jsonify(response_object)), 200

response_object = {
    'status': 'fail',
    'message': resp
}
return make_response(jsonify(response_object)), 401

当状态码为401 时,我目前有此代码失败并显示ERROR Error: Uncaught (in promise): HttpErrorResponse

@Injectable()
export class EnsureAuthenticated implements CanActivate {
    constructor(private auth: AuthService, private router: Router) {}
    canActivate(): Observable<boolean> {
        console.log('AUTH');
        return this.auth.currentUser(localStorage.getItem('token')).pipe(map(suc => {
            if (suc.status = 'success') {
                return true;
            } else {
                this.router.navigateByUrl('/login');
                return false;
            }
        }));
    }
}

我正在使用 Angular 7.0.4。

【问题讨论】:

  • 不,抱歉我删除了标签。

标签: angular observable canactivate


【解决方案1】:

这对我有用 与其返回什么都不做的 false,不如直接返回 UrlTree 以导航到您想去的地方。

canActivate(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
      ):
        | Observable<boolean | UrlTree>
        | Promise<boolean | UrlTree>
        | boolean
        | UrlTree {
        return this.accountClientService.isLoggedIn().pipe(
          map((responseData: ResponseService<boolean>) => {
            if (responseData.model) {
              return responseData.model;
            }
    
            return this.router.createUrlTree(['/signin']);
          }),
          catchError((err) => {
            return of(this.router.createUrlTree(['/signin']));
          })
        );
      }

【讨论】:

    【解决方案2】:

    答案是使用catchError 捕获错误:

    import { Injectable } from '@angular/core';
    import { CanActivate, Router } from '@angular/router';
    import { AuthService } from './auth.service';
    import {Observable, of} from 'rxjs';
    import {catchError, map} from 'rxjs/operators';
    import {HttpErrorResponse} from '@angular/common/http';
    
    @Injectable()
    export class EnsureAuthenticated implements CanActivate {
        constructor(private auth: AuthService, private router: Router) {}
        canActivate(): Observable<boolean> {
            return this.auth.currentUser(localStorage.getItem('token')).pipe(map(suc => {
                if (suc.status = 'success') {
                    return true;
                } else {
                    this.router.navigateByUrl('/login');
                    return false;
                }
            }), catchError((err: HttpErrorResponse) => {
                this.router.navigateByUrl('/login');
                return of(false);
            }));
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-12-21
      • 1970-01-01
      • 1970-01-01
      • 2021-02-20
      • 2019-11-14
      • 1970-01-01
      • 2019-08-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多