Búsqueda de sitios web

angular - ¿Cómo hacer una salida automática del sistema después de que expire un token?


¿Es posible de alguna manera hacer un cierre de sesión automático si el token expiró sin refrescar la página? Es decir, supongamos que una persona estaba en la página de un sitio, la siguió, luego cerró la página o simplemente la apagó, luego regresó después de una hora, y allí se mostrara un mensaje indicando que la salida ocurrió porque el token expiró. Y al mismo tiempo, para mostrar este mensaje, no se necesita refrescar la página o realizar ninguna acción en el sitio.

import { Injectable } from "@angular/core";
import { AuthService } from "../services/auth.service";
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from "@angular/common/http";
import { Observable, throwError } from "rxjs";
import { catchError } from "rxjs/operators";
import { Router } from "@angular/router";

@Injectable()
export class TokenInterceptor implements HttpInterceptor {
  constructor(private auth: AuthService, private router: Router) { }
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (this.auth.isAuthenticated()) {
      req = req.clone({
        setHeaders: {
          Authorization: this.auth.getToken()
        }
      });
    }
    return next.handle(req).pipe(catchError((error: HttpErrorResponse) => this.handleAuthError(error)));
  }
  private handleAuthError(error: HttpErrorResponse): Observable<any> {
    if (error.status === 401) {
      this.auth.signOut(), this.router.navigate(["/sign-in"]), {
        queryParams: {
          sessionFailed: true
        }
      };
    }
    return throwError(error);
  }
}

Respuesta #1

Puedes usar guardias de ruta para esto. Y este es un ejemplo de ello.

// src/app/auth/auth.service.ts
import { Injectable } from '@angular/core';
import { JwtHelperService } from '@auth0/angular-jwt';
@Injectable()
export class AuthService {
  constructor(public jwtHelper: JwtHelperService) {}
  // ...
  public isAuthenticated(): boolean {
    const token = localStorage.getItem('token');
    // Check whether the token is expired and return
    // true or false
    return !this.jwtHelper.isTokenExpired(token);
  }
}

// src/app/auth/auth-guard.service.ts
import { Injectable } from '@angular/core';
import { Router, CanActivate } from '@angular/router';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuardService implements CanActivate {
  constructor(public auth: AuthService, public router: Router) {}
  canActivate(): boolean {
    if (!this.auth.isAuthenticated()) {
      this.router.navigate(['login']);
      return false;
    }
    return true;
  }
}

// src/app/app.routes.ts
import { Routes, CanActivate } from '@angular/router';
import { ProfileComponent } from './profile/profile.component';
import { 
  AuthGuardService as AuthGuard 
} from './auth/auth-guard.service';
export const ROUTES: Routes = [
  { path: '', component: HomeComponent },
  { 
    path: 'profile',
    component: ProfileComponent,
    canActivate: [AuthGuard] 
  },
  { path: '**', redirectTo: '' }
];