Sinan Samet
Sinan Samet

Reputation: 6752

How can I check if the authentication is still valid and redirect after?

Like the title says. I check the authentication using a request to the API. If the requests returns false, I want to log the user out. However if I do this with a guard, it doesn't work because it runs synchronously and I can't wait for the request to show the page each time I go to another page.

Example:

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    this.authService.checkAuth(); // Sends request to backend for auth validation
    return this.authService.getIsAuthenticated(); // Shows/doesn't show page before validation
  }

If I run it async, it would wait every time for the response before it shows the page. I want it to show the page during the request, but if the request returns false, I want to logout ie this.authService.logout().

Can I achieve this without putting it in the IonicViewDidLoad of every page?

The scenario:

A user is logged in on two devices. The user unlinks one of the devices. So during the session, the other device needs to be logged out.

Possibly immediately. But I suspect this would require an interval to continueously check if the device is still logged in. Therefore it would suffice to do this on change of a page (like in the guard).

Upvotes: 0

Views: 995

Answers (2)

Sinan Samet
Sinan Samet

Reputation: 6752

The problem with my solution was that my authentication works with a behavior subject. For that reason it didn't work like I wanted when I changed it in the canActivate. However I managed to solve this (in combination with the interceptor solution of @Roma Ruzich) by checking if the authorization is still valid. If not, log out.

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    this.authService.getAuthStatus().subscribe((data: any) => {
      if (!data.deviceRegistered) {
        this.authService.logout();
      }
    });
    return this.authService.getIsAuthenticated();
  }

Upvotes: 0

Roma Ruzich
Roma Ruzich

Reputation: 752

I use jwt token to authorization handle. There is part of code (interceptor) where I check if user is authenticated:

 intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any> | any> {

    return next.handle(this.addTokenToRequest(request, this.authService.getToken()))
      .pipe(
        catchError(err => {
        if (err.status === 0 || err.status === 401) {
            // if server return 401 Unauthorized
            this.authService.logout();
            location.reload(true);
        } else if (err.status === 302) {
          this.router.navigate(['/pages/technical-works']);
        } else {
              return throwError(err.error);
            }
          }));

      private addTokenToRequest(request: HttpRequest<any>, token: string): HttpRequest<any> {
           return request.clone({ setHeaders: { Authorization: `Bearer ${token}` } 
                               });
      }
}

So If server return unauthorized error then i logout in client side.

Upvotes: 1

Related Questions