Issue
I have checkAuth function in ngOnInit in app.component.ts which checks localStorage for token and if token is valid authService logs you in.
Also, I have AuthGuard in /profile route which checks if you logged in.
If I click the link in the navbar this works great, but if I go to link directly authGuard working before my checkAuth function and returns false.
Where do I need to place my checkAuth function to make it work correctly?
Or maybe I need to change something in AuthGuard or in app.component
Here is AuthGuard code
@Injectable({
providedIn:'root'
})
export class AuthGuard implements CanActivate, CanActivateChild {
constructor(private auth:AuthService, private router:Router) {
}
canActivate(route:ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable<boolean>{
console.log(this.auth.isAuth)
console.log(this.auth.isLoggedIn())
if (this.auth.isLoggedIn()){
return of(true)
} else {
this.router.navigate(['/login'])
return of(false)
}
}
canActivateChild(route:ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable<boolean>{
return this.canActivate(route, state)
}
}
app.component
ngOnInit() {
if (localStorage.getItem('token')){
this.auth.checkAuth().subscribe(
(data) => {
console.log(data)
console.log(this.auth.isAuth)
}
)
}
}
and checkAuth in AuthService
checkAuth():Observable<UserDto>{
return this.http.get<UserDto>(`/api/user/refresh`, {withCredentials:true, observe:'body', responseType:'json'})
.pipe(
tap(
(data) => {
localStorage.setItem('token', data.accessToken)
this.setAuth(true)
this.setUser(data.user)
},
(error) => {
console.log(error)
}
)
)
}
Solution
If you want checkAuth to run before the guard, you have to make it a guard as well, and use it before the guard that you already have. E.g: canActivate: [CheckAuthGuard, AuthGuard].
This is what's going on right now:
First scenario - accessing /profile by clicking in the navbar
- You access the application's root component
- Whatever guards you have on the root route run
- The root component is initialized and
AppComponent.ngOnInit()runs, thus runningcheckAuth() - You click the link in the navbar to go the
/profileroute - Guards for the profile route are run
Second scenario - accessing /profile by visiting the URL directly
- You access the application's root component, but this time it is routed to the
/profileroute - Whatever guards you have on the profile route run
- The root component and it's child are initialized, running their
ngOnInit()methods
See? In the second scenario, the guard runs before ngOnInit and checkAuth. I advise you to put some console.log calls on your app, so you can more easily see the order in which things are happening.
Basically this is it, guards run before the component is rendered, so you should keep that in mind. Extract your checkAuth call to a guard and you'll be fine.
Answered By - Allan Juan
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.