Search code examples
angularrxjsngrx

how do I use an auth guard with NGRX


I am using NGRX in an Angular app and I'm trying to use an auth guard. when the app starts, I dispatch an action that gets the auth status from the server (firebase). The issue is if I go directly to a link that is guarded by an auth guard, the default auth state is false so that gets returned and it redirects to the login page.

Here is my canActivate method

canActivate() {
        return this.store.select(fromAuth.getAuthenticatedStatus).pipe(
            //filter(isAuth => isAuth == true || isAuth == false),
            take(1),
            map((isAuth: boolean) => isAuth),
            catchError(() => of(false))
        )
    }

Is there a way to wait until the auth status comes back from the server before checking the store for the auth status? I've tried filter and removing the take operator but it didn't seem like that worked.

I don't want to put the call to the server in the auth guard because I don't want it to check the server every time I switch pages.


Solution

  • There You have:

    @Injectable()
    export class LoggedGuard implements CanActivate {
    
        constructor(private auth: AngularFireAuth, private router: Router) { }
    
        canActivate() {
            return this.auth.authState.pipe(
                take(1),
                map(user => !!user), // !! convert User object to boolean value
                tap(isLogged => {
                    if(!isLogged) {
                        this.router.navigate(['/login'])
                        console.log("You are not logged in. You cannot access route.")
                    }
                })
            )
        }
    }
    

    In this situation i prefer to make a request to firebase to get the fresh authentication status not taking it from store. This is more important if You make guards for someone with some claims, because if You remove some one admin he might have still old claims.

    Firebase have his own IndexedDB if You connect store to some 'LocalDatabase' in browser and by mistake your app will retrieve data from local and will not check for updates You can have endless logged in user even You ban him and delete his account.