我正在开发一个Web应用程序,并在Angular前端代码中定义了以下isLoggedIn()
函数来检查用户是否已通过身份验证:
@Injectable()
export class AuthService {
// irrelevant code is omitted for brevity
private currentUserSubject = new BehaviorSubject<User>(
JSON.parse(localStorage.getItem(AuthService.KEY_USER))
);
isLoggedIn(): boolean {
return this.currentUserSubject.value &&
(this.currentUserSubject.value.expiresAtMillis > Date.now());
}
}
在我的路由模块中,我具有以下路由定义:
{ path: ':id', component: DetailsComponent, canActivate: [AuthGuard, IdGuard] }
AuthGuard
检查用户是否登录:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
if (this.authService.isLoggedIn()) {
return true;
}
return false;
}
然后IdGuard
检查id
参数是否为数字:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
if (isNaN(Number(route.paramMap.get('id')))) {
return false;
}
return true;
}
这一切正常,仅当用户通过身份验证并且id
参数是一个数字时,该路由才可以访问。
当我将AuthGuard
代码更改为更惯用时,就会发生问题:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
// old code
// if (this.authService.isLoggedIn()) {
// return true;
// }
// return false;
// new code
return this.authService.isLoggedIn();
}
使用此新代码,即使用户未未通过认证,也可以访问该路由。
如果我从路线中删除了IdGuard
(因此仅应用了AuthGuard
),那么它可以正常工作,,所以我猜想它必须与这两个后卫如何互动彼此,但我无法找出确切的问题。
如果有人能向我解释这种行为,我将非常感激。
编辑:
我认为我已经找到问题了。如果currentUserSubject.value
为null
,则以下表达式返回null
而不是true
或false
:
return this.currentUserSubject.value &&
(this.currentUserSubject.value.expiresAtMillis > Date.now());
因此,以下各项按预期工作:
// checking explicitly for null
return this.currentUserSubject.value == null &&
(this.currentUserSubject.value.expiresAtMillis > Date.now());
这也是:
// converting to Boolean
return Boolean(this.currentUserSubject.value) &&
(this.currentUserSubject.value.expiresAtMillis > Date.now());
但是为什么会这样呢?
在这样的表达式中使用this.currentUserSubject.value
是否应该自动转换为Boolean
值吗?