Disconnect users or authenticate them again if the server is restarted - Angular 2

Asked

Viewed 318 times

0

I have an Angular 2 application that is consuming an API in Nodejs. This application has JWT authentication. My problem is this: When the Node server is restarted, the user is still able to navigate between pages, but does not see what is being requested for the API.

This is because when the user connects to the system, I store his token in the application’s localStorage and create a session in the . Even if the server is offline, the variable in localStorage will still be present.

Here’s my canActivate (protecting all routes and redirecting if necessary):

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {

const currentUser = this.authenticationService.currentUserValue;
if (currentUser) {
  // authorised so return true
  if (currentUser.permissions.basic_permissions === true && currentUser.permissions.owner === false) {

    this.router.navigate(["/demo"]);
  }
  return true;
}

// not logged in so redirect to login page with the return url
this.router.navigate(["/login"], { queryParams: { returnUrl: state.url } });
return false;
}

Authentication service by logging in:

login(username: string, password: string) {
return this.http
  .post<any>(
    `${this.APIEndpoint}/login`,
    { username, password },
    { withCredentials: true }
  )
  .pipe(
    map(user => {
      if (user && user.userInfo.token) {
        localStorage.setItem("currentUser", JSON.stringify(user.userInfo));
        this.currentUserSubject.next(user.userInfo);
        this.loggedIn = true;
      }

      return user.userInfo;
    })
  );
}
  • Do you have access to your backend ? Do you know or have any warning somewhere where you are notified that the crash occurred ? If the answer is yes, part of that principle, look where some kind of Logg is stored, now if the fall is for server reasons where you do not know whether or not the fall occurred, it will be necessary to implement a verification logic, from time to time, or at certain times, the detail is how will make this check, I would try something like using the ping on the server address, if false answer, performs appropriate procedures

  • Yes, I have access to the back-end. However, I would like to do this on the Front. I believe I am more productive. I thought about leaving the front with a function from time to time checking the server, however, I believe that it would not be nice to create a timer just for this

  • Unfortunately in this scenario, it’s the only way to get what you want

  • 1

    Actually I disagree, one of the ways I was able to do it was from a server socket. Once the socket drops, most likely the server is out.

1 answer

1

There are N possible solutions to this type of problem. I will demonstrate how I do this in my applications.

A request to the server (using httpClient from common angular) as follows:

this.billsService.getBill(billId)
 .subscribe( res => {

       */ código caso haja sucesso na comunicação com a API */

  }, err => this.alertService.error('Houve um erro ao buscar a dívida. Falha na comunicação com a API'));

In case the subscribe falls into the error (where it could not communicate with the server), I inform a message to the user, stating that there was some kind of error.

But if you want to disconnect the user, just create one canActivate that makes a request for your back-end, and in case your subscribe falls into error, you force the user logout.

Example of a code where I do something similar:

// metodo dentro do meu canActivate this.authService.isUpdated() .subscribe( () => {}, err => this.authService.logout() );


EDIT: (example of a complete application)

export class AuthGuard implements CanActivate {

constructor(
    private userService: UserService,
    private router: Router,
    private authService: AuthService,
    private alertService: AlertService) {}

canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): boolean | Observable<boolean> | Promise<boolean> {

    if (!this.userService.isLogged()) {
        this.router.navigate(['signin']);
        return false;
    }

    this.authService.isUpdated()
        .subscribe( res => {
            const response = res.body as ResponseApi;

            if (!response.error) {

                const currentBuild = response.data as SystemVersion;
                const localBuild   = this.authService.getCurrentVersionLoged();

                if (!(currentBuild.version === localBuild.version)) {
                    this.userService.logout();
                }

            } else {
                this.alertService.error('Não foi possível verificar as atualizações do sistema');
            }
        }, err => this.alertService.error('Não foi possível verificar as atualizações do sistema'));

    return true;
}

}

  • Is it possible to place more than one method inside the canActivate? When I tried to make a request inside it for my back-end, it seemed to me that he was making the request, but did not carry out the rest of the logic I already have in the code reported above

  • @Matheusbernardi Yes, you can use as many methods as you want within your canActivate. it is only terminated if there are any exceptions or when you return true or false. I will edit my reply and add an example where I use more than one method to validate the route;

Browser other questions tagged

You are not signed in. Login or sign up in order to post.