【发布时间】:2020-09-24 16:17:38
【问题描述】:
我正在实施一个有角度的 AdmingGuard 来保护一些路由。
管理员警卫:
// --------------ADMIN GUARD
// want protect routes from user who are not Admin
canActivate(): boolean {
// isLogged() service method: set 2 global boolean variable in teh service:
//- 'isLogged'= true if the user is logged in
//- 'adminLoggedIn' = true if the logged user is an Admin
this.authService.isLogged();
// getIsAdminLogged() service method: return value of global var 'adminLoggedIn'
const adminLoggedIn = this.authService.getIsAdminLogged();
if (adminLoggedIn) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}
服务:
// SERVICE
//here global variable:
loggedIn: boolean; // the user is logged ?
adminLoggedIn: boolean; // the logged user is an Admin ?
constructor(private http: HttpClient, private router: Router) {}
// this makes an Http Request to the server sending the AccessToken
// and control if the user that sent the AccesToken is logged and if is an Admin
isLogged() {
// get the AccessToken from localStorage, if is empty: im sure the user is not logged
const accessToken = this.getAccessToken;
if (typeof accessToken === 'undefined' || accessToken === null) {
this.loggedIn = false;
this.adminLoggedIn = false;
return;
}
// here makes the https ruquest to the server
return this.http
.get<any>(this.isLoggedUrl)
.pipe(catchError(this.errorHandler))
.subscribe(
(res) => {
// server send back the 'res' response
// control in the 'res' if the user is logged and if the user is an Admin
// in base on this controls, set the 2 global var 'loggedIn' and 'adminLoggedIn'
if (res.status == 200) {
this.loggedIn = true;
if (res.userType == 'admin') {
this.adminLoggedIn = true;
}
} else {
this.adminLoggedIn = false;
}
},
(err) => {
// server sand back some error
// control if the error is 'TokenExpiredError' (in that case try to refresh the tokens)
// otherwise set the 2 vars 'loggedIn' and 'adminLoggedIn' to false
if (err.error.message == 'TokenExpiredError') {
const refreshToken = this.getRefreshToken;
if (typeof refreshToken === 'undefined' || refreshToken === null) {
this.loggedIn = false;
this.adminLoggedIn = false;
} else {
// refresh tokens if possible
// also this method set the var 'loggedIn' and 'adminLoggedIn'
this.refreshTokens();
}
} else {
this.loggedIn = false;
this.adminLoggedIn = false;
}
}
);
}
// return the value of the global var 'adminLoggedIn'.
getIsAdminLogged() {
return this.adminLoggedIn;
}
问题是
按照它应该执行的 CanActivate 中的语句顺序:
- isLogged();在 isLogged() 内部执行 HTTP 请求以验证用户是否已登录以及用户是否为管理员。所以将服务 2 全局变量 'loggedIn' 和 'adminLoggedIn' 中的 isLogged() 设置为 true 或 false。
- getIsAdminLogged();获取 'adminLoggedIn' 的值来检查登录的用户是否是管理员(这个 Guard 的目标)
但是 HTTP 请求不是异步的,所以 getIsAdminLogged();在该 HTTP 请求验证用户是否为管理员之前执行。
我已经阅读了一些关于它的解决方案,但我仍然感到困惑。
谢谢
【问题讨论】:
标签: angular http observable angular-router-guards