当出错时,Angular Authgaurd在无限循环中发出请求

时间:2018-02-19 09:27:45

标签: angular

我正在尝试使用authGaurd保护我的路线。

auth.service.ts

import { Injectable } from '@angular/core';
import { environment } from '../../../environments/environment';
import { Router, CanActivate } from '@angular/router';
import { HttpClient, HttpHeaders } from '@angular/common/http';

import { Observable } from 'rxjs/Observable';

import { Response } from '../response.model';

const httpOptionsSecure = {
    headers: new HttpHeaders({'Content-Type': 'application/json', 'Authorization': 'Bearer ' + localStorage.getItem("authToken")})
}

@Injectable()
export class AuthService implements CanActivate {

    private baseUrl: string = environment.baseUrl + "auth/";
    private signInUrl: string = this.baseUrl + "signIn";
    private verifyUserUrl: string = this.baseUrl + "verify";

    constructor(private http: HttpClient, public router: Router) {

    }


    canActivate(): Observable<boolean> {
        return new Observable((observer) => {
            this.verifyUser().subscribe((res) => {
                if (res.code === 200 && res.isSuccess === true) observer.next(true);
                else observer.next(false);
            }, (err) => {
                console.log("Err: ", err);
                this.router.navigate(['/','login']);
                observer.next(false);
            });
        });
    }

    // Verify loggedIn User
    verifyUser(): Observable<Response> {
        return this.http.post<Response>(this.verifyUserUrl, {}, httpOptionsSecure);
    }

因此,每当我尝试访问受保护的页面时,只要服务器的响应为400代码,就会在infinte循环中再次发出请求。

我对角色有点新意,我不知道自己做错了什么。

提前致谢。

1 个答案:

答案 0 :(得分:1)

很可能您正在进入无限循环,因为/ path被重定向到受AuthGuard本身保护的路径。

所以举个例子。您尝试访问受保护的路由A,路由A重定向到路由B(基本路由/),路由B可以重定向(查看路由中的redirectTo属性)到路由C,它也受到AuthGuard的保护,导致以下路线。

A - &gt; B - &gt; C - &gt; B - &gt; ç...

确保路由定义正确。

请注意,为与

关联的每个路线激活路线保护

例如,如果你有

/            <- Associated with an Auth Guard
/route1      <- Child of /
/route2      <- Child of /

具有以下路线定义

let routes:Routes = [
    { 
       path: '',
       canActivate: [ AuthGuard ]
       children: [
         { path: '', redirectTo: 'route1', pathMatch:'full' },
         { path: 'route1' },
         { path: 'route2' }
       ]
    }
];

尝试访问其中一个路由,将触发与路由/关联的AuthGuard。例如,如果你去route1,将会触发auth Guard,它将重定向到/route1会再次重定向到Observables,然后重新开始循环。

我建议您阅读this documentation guide以获取有关路由如何工作的更多信息。

此外,RxJS的使用与Angular无关,但是import { Observable } from 'rxjs/Observable'; import { catchError, map, of } from 'rxjs/operators'; canActivate(): Observable<boolean> { return this.verifyUser().pipe(map((res) => { if (res.code === 200 && res.isSuccess === true) { return true; } this.router.navigate(['/','login']); return false; }, catchError((err) => { console.log("Err: ", err); this.router.navigate(['/','login']); return of(false); })); } // Verify loggedIn User verifyUser(): Observable<Response> { return this.http.post<Response>(this.verifyUserUrl, {}, httpOptionsSecure); }

您的代码可以简化如下

对于RxJS 5.5.x +

canActivate(): Observable<boolean> {
    return this.verifyUser().map((res) => {
        if (res.code === 200 && res.isSuccess === true) {
            return true;
        } 

        this.router.navigate(['/','login']);
        return false;
    }).catch((err) => {
        console.log("Err: ", err);
        this.router.navigate(['/','login']);
        return Observable.of(false);
    });
}

// Verify loggedIn User
verifyUser(): Observable<Response> {
    return this.http.post<Response>(this.verifyUserUrl, {}, httpOptionsSecure);
}

对于RxJS 5.4.x及以下

MultiLabelBinarizer