我在Angular中使用canActivate
使用guards
。我想检查用户是否已通过身份验证,并根据结果保护路由。
用户有两种类型:Type1
和Type2
,因此可以通过Type1
,Type2
或unauthenticated
验证用户。
以下guard
适用于Type1
用户。
这是我的代码:
constructor(private authservice: AuthService, private router: Router, private route: ActivatedRoute){}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean{
const self = this;
const expectedType = "type1";
this.authservice.isUserAuthenticatedbyType(expectedType).then(
function(data){
if(data === false){
console.log(data);
self.router.navigate(['/'], {relativeTo: self.route});
}
return data;
},
function(error){
self.router.navigate(['/']);
return false;
}
);
return false;
}
问题是我进行API调用以验证用户是否已通过身份验证,并且在从API返回结果之前执行return false;
。因此,我暂时看到一个不同的页面,然后将其路由到正确的页面。如何解决此问题,我不想在API调用之前返回false或true,但是不这样做会产生错误。
我还尝试了以下方法:
return this.authservice.isUserAuthenticatedbyType(expectedType)
但是对于http://localhost:4200
用户,这只是将我导航到unauthenticated
网址。
我有以下路线:
{ path: "", component: HomeComponent },
因此,在上述情况下,应该已调用HomeComponent
,但是没有调用HomeComponent的ngOnInit
。
答案 0 :(得分:2)
如果您使用的是promise
,请尝试类似的操作-主要想法是保持路由,直到您完成Api
的呼叫-我遇到了同样的问题,我通过返回{{1 }}在我的Promise<boolean>
上
route
此方法解决了我的问题-等待 API 返回数据并为路线指明方向
希望它能正常工作-编码愉快!!
答案 1 :(得分:1)
您可以这样实现:
public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.authservice.isUserAuthenticatedbyType("type1").pipe(
map(data => {
if (data === false) {
this.router.navigate(['/']);
return false;
}
return !!data;
}),
catchError(() => {
this.router.navigate(['/']);
return of(false);
}),
);
}
从Angular 7.1.0开始(请注意,它在7.0.x中不是 ),也可以改为执行此操作,如果您有多个防护,它会更短且更可预测:
public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.authservice.isUserAuthenticatedbyType("type1").pipe(
map(data => data === false ? this.router.parseUrl("/") : !!data)
catchError(() => this.router.parseUrl("/")),
);
}
答案 2 :(得分:1)
您也可以这样尝试:
canActivate(): Observable<boolean> | Promise<boolean> | boolean {
return new Promise(res => {
this.authservice.isUserAuthenticatedbyType("type1").subscribe(
(data) => {
if (data === true) {
res(true);
} else {
this.router.navigate(['/']);
res(false);
}
},
(error) => {
this.router.navigate(['/']);
res(false);
}
);
});
}