如何解决Angular 12:canActivate Guard 在页面刷新时不起作用
我的 canActivate 守卫是这样工作的:如果当前(fire auth)用户有一个用户配置文件,那么他就可以访问该路由。否则,我会将他路由到个人资料创建页面。
这很好用,除非我刷新页面!
守卫:
export class UserProfileGuard implements CanActivate {
constructor(private authService: AuthService,private router: Router) { }
canActivate(route: ActivatedRouteSnapshot,state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if (this.authService.userProfile) {
return true;
}
this.router.navigate(['user/createprofile']).then();
return false;
}
}
身份验证服务:
export class AuthService implements OnDestroy {
public userProfile: UserProfile | null = null;
private subscription: Subscription | undefined;
constructor(public fire: AngularFireAuth,private httpService: HttpHandlerService) {
this.subscription = this.fire.authState.subscribe(fireAuthUser => {
if (fireAuthUser) {
this.httpService.getMyProfile().subscribe((profile: UserProfile) => {
this.userProfile = profile;
})
}
});
}
}
因此,如果我在受保护的路线上并刷新页面,即使存在配置文件,我也会始终被发送到配置文件创建页面。
我担心守卫会在刷新时过早检查,此时身份验证服务尚未获取配置文件。
你能帮我解决这个问题吗?
提前致谢!
解决方法
确保您的守卫正在等待 API 获取数据。
export class UserProfileGuard implements CanActivate {
constructor(private authService: AuthService,private router: Router,private httpService: YourService) { }
canActivate(route: ActivatedRouteSnapshot,state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return checkUser();
}
checkUser(): Observable<boolean> {
this.httpService.getMyProfile().subscribe((profile: UserProfile) => {
// Do your if the profile exists check
return true if they have profile
return false if they don't
})
}
}
,
canActivate 接受 Observable 作为返回类型。因此,您可以返回 Observable,而不是直接返回 true/false 此外,您可以返回一个 UrlTree,而不是编写 router.navigate,它会在这种情况下自动重定向。
canActivate(route: ActivatedRouteSnapshot,state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.authService.getUserAuth().pipe(
map((authResponse) => {
if(authResponse) {
return true;
}
return this.router.createUrlTree(['user,'createprofile']).toString()
}),catchError(() => {
return this.router.createUrlTree(['user,'createprofile']).toString()
}))
}
在您的服务中,您可以添加一个方法来返回 auth observable。
userProfile = null;
getUserAuth: () => {
if(userProfile) {
return of(userProfile)
}
return this.fire.authState.pipe(switchMap((fireAuthUser) => {
if(fireAuthUser) {
return this.httpService.getMyProfile()
}
return throwError('No Auth User found!')
}),tap((profile) => this.userProfile = profile)
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。