Angular 2路由器 - CanActivate Guard

时间:2016-06-25 15:59:11

标签: angularjs angular angular-routing

如果他们的会话无效,我实施了一个CanActivate后卫来将用户重定向到登录页面。

关于会话是否有效的检查是通过服务完成的,因此从保护我订阅服务调用以获得会话有效状态。

我已经调试了代码,所有内容似乎都应该正常工作,事实上当会话无效时,应用程序会重定向回登录页面。但是,当我从警卫处返回true时,页面未加载。

我的代码与Angular documentationCode on Plunker)上列出的内容类似。

我不确定自己是否在守卫本身实施了一些错误。我可以看到的差异在于警卫正在访问服务中的一处房产 - 但我认为这不应该太重要。据我所知,从守卫返回true只会继续正常的路由操作。

注意:我正在使用Angular RC3

代码:

保护

export class MyGuard implements CanActivate {
    constructor(private checkSessionService: CheckSessionService, private router: Router) {}

    canActivate(
    next:  ActivatedRouteSnapshot,
    state: RouterStateSnapshot
    ) {
        this.checkSessionService.checkUserSession(localStorage.getItem('userToken'))
        .subscribe(validSessionReturn => {

            if (validSessionReturn) {
                return true;
            } else {
                // redirect to login
                this.router.navigateByUrl('/login');
                return false;
            }
        },
        error => console.log(error));
    }
}

修改

我进一步调查过,看起来我遇到的问题与我尝试从订阅方法本身返回boolean这一事实有关。作为测试,我尝试了以下内容,一切都按预期工作:

export class MyGuard implements CanActivate {
    constructor(private checkSessionService: CheckSessionService, private router: Router) {}

    canActivate(
    next:  ActivatedRouteSnapshot,
    state: RouterStateSnapshot
    ) {
        if(localStorage.getItem('userToken') !== null) {
            return true; // or return Observable.of(true);
        } else {
            return false; // or return Observable.of(false);
        }
    }
}

您可以从上面的代码中注意到,可以返回booleanObservable<boolean>。我已实施的CheckSessionService确实会返回Observable<boolean>。事实上,当我尝试下面的代码时,一切都按预期工作,这意味着如果会话有效,页面将成功加载,否则路由将停止:

export class MyGuard implements CanActivate {
    constructor(private checkSessionService: CheckSessionService, private router: Router) {}

    canActivate(
    next:  ActivatedRouteSnapshot,
    state: RouterStateSnapshot
    ) {
        return this.checkSessionService.checkUserSession(localStorage.getItem('userToken'));
    }
}

但是,根据上面的示例,我无法根据服务检索到的值找到重定向到特定页面的方法。我现在的问题是,是否有一种方法可以在没有订阅方法的情况下检查this.checkSessionService.checkUserSession(localStorage.getItem('userToken'))的结果,或者如何从subscribe方法返回的方式不同。我试过了:

if(this.checkSessionService.checkUserSession(localStorage.getItem('userToken')) === Observable.of(false))

但正如预期的那样它无效。

1 个答案:

答案 0 :(得分:2)

替换

this.checkSessionService...

通过

return this.checkSessionService...

除了订阅observable并返回subscrption之外,你还必须返回observable本身,但是如果它是假的则插入一些东西:

return this.checkSessionService.checkUserSession(localStorage.getItem('userToken'))
    .do(‌​function(authenticated) { 
        if (!authenticated) ... 
    });