我在 Angular 中使用canActivateusing 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;
}
Run Code Online (Sandbox Code Playgroud)
问题是我进行了 API 调用以验证用户是否已通过身份验证并return false;在 API 结果之前执行。所以,暂时我看到一个不同的页面,然后它被路由到正确的页面。我该如何解决这个问题,我不想在 API 调用之前返回 false 或 true,但不这样做会导致错误。
我还尝试了以下方法:
return this.authservice.isUserAuthenticatedbyType(expectedType)
Run Code Online (Sandbox Code Playgroud)
但这只是将我导航到用户的http://localhost:4200url unauthenticated。
我有以下路线:
{ path: "", component: HomeComponent },
Run Code Online (Sandbox Code Playgroud)
所以,在上面的场景中,HomeComponent应该被调用,但是ngOnInitHomeComponent 没有被调用。
你也可以这样尝试:
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);
}
);
});
}
Run Code Online (Sandbox Code Playgroud)
你可以这样实现:
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);
}),
);
}
Run Code Online (Sandbox Code Playgroud)
从 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("/")),
);
}
Run Code Online (Sandbox Code Playgroud)
如果您正在使用promise类似这样的尝试 - 主要想法是保持您的路由直到您的Api通话完成 - 我遇到了同样的问题,我已经通过返回Promise<boolean> 我的route护卫来实现它
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean{
const self = this;
const expectedType = "type1";
retrun new Promise(res => {
this.authservice.isUserAuthenticatedbyType(expectedType).then(
function (data) {
if (data === false) {
console.log(data);
self.router.navigate(['/'], { relativeTo: self.route });
}
res(data);
},
function (error) {
self.router.navigate(['/']);
res(false);
}
);
});
}
Run Code Online (Sandbox Code Playgroud)
这种方法解决了我的问题 - 它一直等到API返回数据并为路线指明方向
希望它会起作用 - 快乐编码!!
| 归档时间: |
|
| 查看次数: |
4242 次 |
| 最近记录: |