0

I have an Angular web application who makes requests to a GraphQL API through Apollo Client.

I want to guard my angular routes based in the user login status. When a user logs in, receives a cookie from the server with 2 hours expiration limit.

I don't know how to check if the user is logged in the application, I've tried with checking the cookie but it has httpOnly attribute (cannot disable it). I don't want to use Session Local Storage because i think it's harder to control when the cookie has expired. So I am trying with making a account data request to the Apollo server, and if the request is successful, then the user is logged in. But I am having issues in the auth guard to wait for the response before anything. This is my code:

//auth.service.ts
[...]
export class AuthService {
    constructor(
        private myAccountGQL: MyAccountGQL
    ) {}

    //The function makes the request and has to return boolean if success or error
    isLogged(): boolean {    //(I know it's bad implemented)
        this.myAccountGQL.watch().valueChanges.pipe(
            map(({ data, loading, error }) => {
                console.log(data);
                console.log(loading);
                console.log('error', error);
            })
        );
    }
}
//auth.guard.ts
export class AuthGuard implements CanActivate {
    constructor(private authService: AuthService, private router: Router) {}

    canActivate(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
    ):
        | Observable<boolean | UrlTree>
        | Promise<boolean | UrlTree>
        | boolean
        | UrlTree {
        const url: string = state.url;
        return this.checkLogin(url);
    }

    checkLogin(url: string): true | UrlTree {
        if (this.authService.isLogged()) { //¿How do I wait for the request to be completed?
            return true;
        }

        this.authService.setRedirectUrl(url);

        return this.router.parseUrl('/login');
    }
}

1 Answers1

1
  1. A GraphQL query or mutation should return a promise - you should wait for the promise to resolve with await or .then()
  2. Your client needs to store the logged in state somewhere (local storage or cookie). Otherwise you have to check your status with the server before every single query which would be tedious.

Your cookie may be http only because you're in development and your localhost is http and not https.

Michel Floyd
  • 18,793
  • 4
  • 24
  • 39
  • Thanks for your answer! The cookie is a 'connection.sid' cookie, I would set the httpOnly property to false from express server, but I read that property is important for security (and even if I disable the property I cannot get the expiration limit with npx-cookie-service), how could I send multiple cookies from server or save in local storage the expiration limit? – Santiago Vallejo Oct 28 '22 at 17:20
  • That's a different question :) – Michel Floyd Oct 28 '22 at 17:39