为什么无法在canActivate方法的catch块中返回Obeservable.of(false)?

时间:2018-08-01 06:50:22

标签: angular typescript auth-guard

我使用canActivate功能来保护某些路由(管理员)。对于这种情况,我确实使用了authGuard类/函数:

问题是,当我尝试以以下形式返回可观察的布尔值: return Observable.of(false); 时,它无法按预期运行,并引发以下错误:

  

'(err:any)类型的参数=>可观察|无法将Observable分配给类型为(err:any,catched:Observable)=> ObservableInput'的参数。     键入“可观察|无法将“可观察”分配给“可观察输入”类型。       类型“可观察”不能分配给类型“可观察输入”。         类型“可观察”不能分配给类型“ ArrayLike”。           类型“可观察”中缺少属性“长度”。

我一直在搜索并发现这种问题的种类,但不完全相同。提供的提示/解决方案是使用.throw(err);

当我将返回值更改为: return Observable.throw(err); 时,该错误消失了,但是并没有返回false,这是为了保护我的路线。< / p>

我认为这是类型问题,但我无法解决,因此我不断返回observable.of(false)

canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable<boolean> | Promise<boolean> | boolean {
        return this.userService.getAdminAuth()
        .map( (res) => {
            if ( res === true) {
                return true;
            } else {
                ......
                return false;
            }
        })
        .catch( (err) => {
            if ( err.status === 403 ) {
                console.log(`403:  ${err.status}`);
                return this.userService.refreshToken()
                    .map( (res) => {
                        console.log(`Res RefreshToken: ${res}`);
                    });
            }
            return Observable.of(false); // protect route!
        });
}

user.service.ts中的功能:

....

isAdminAuthenticated = false;

public getAdminAuth() {
    console.log('Saved token: ' + localStorage.getItem('ac_token') );
    if ( this.isAdminAuthenticated === true ) {
        return Observable.of(true);
    } else {
        return this.http.get(
           'URL', { 
              headers: new HttpHeaders({"Accept": "application/json"}), 
              withCredentials: true, 
              observe: "response" 
           }
        )
        .map((res) => {
            if (res.status === 200) {
                this.isAdminAuthenticated = true;
                return true;
            } else {
                return false;
            }
        }, (err) => {
            console.log('Error: ' + err);
            return false;
        });
    }
}


refreshToken() {
    return this.http.get(
        'URL', 
        { 
            headers: new HttpHeaders(
                {
                    "Accept": "application/json",
                    "Authorization" : "Bearer " + localStorage.getItem('ac_token')
                }
            ), 
            withCredentials: true, 
            observe: "response" 
        }
    )
}

另一方面,如果我将refreshToken函数更改为:

refreshToken() {
        return this._http.get(
            'URL', 
            { 
                headers: new HttpHeaders(
                    {
                        "Accept": "application/json",
                        "Authorization" : "Bearer " + localStorage.getItem('ac_token')
                    }
                ), 
                withCredentials: true, 
                observe: "response" 
            }
        ).map( (res) => {
            console.log(`Res: ${JSON.stringify(res)}` );
        }), (err) => {
            console.log(`Err: ${JSON.stringify(err)}` );
        };
}

然后错误提示:

  src / app / admin.guard.ts(38,9)中的

ERROR:错误TS2322:类型'Observable'不能分配给类型'boolean |承诺|可观察的”。     类型“可观察”不能分配给类型“可观察”。       输入'boolean | {}”不可分配为“ boolean”类型。         类型“ {}”不可分配给类型“布尔”。   src / app / service.guard.ts:错误TS2339:类型“((err:any)=> boolean”)上不存在属性“ map”。

1 个答案:

答案 0 :(得分:1)

因为您应该使用return Observable.throw(false)of成功,throw错误。