Búsqueda de sitios web

javascript - cómo usar AuthGuard correctamente


Tengo una aplicación Angular donde quiero usar authguard para proteger algunas rutas, pero por alguna razón no funciona. Primero hago una solicitud POST a mi backend de Spring Boot, si eso me da éxito, establezco un valor en true y compruebo ese valor en mi método canActivate. Pero no funciona, ni siquiera entra en ese método. Pensé que se llamaba automáticamente si lo configuraba en mi ruta en app-route.module. ¿Cómo puedo usarlo correctamente?

Servicio de autenticación con authguard juntos:

export class AuthenticationService {




  constructor(
    private http: HttpClient,
    private router: Router,

  ) { }

  authenticateUser(login: LoginModel){
    return this.http.post(environment.rootUrl + 'authenticate', {
      username: login.username,
      password: login.password,
    }).subscribe({
      next: (data) => {
       localStorage.setItem('token', data.toString())
      }, error: (error) => {
        this.isAuthenticated = false
      }
    })
  }

  isUserLoggedIn(){
    return !!localStorage.getItem('token')
  }

  
}

Authguard :

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {

  constructor(
    private auth: AuthenticationService,
    private router: Router
  ) {
  }

  canActivate(): Promise<boolean> {
    return new Promise(resolve => {
      if (this.auth.isUserLoggedIn()) {
        resolve(true)
      } else {
        this.router.navigate(['authenticate'])
        resolve(false)
      }
    })
  }
}

Módulo de la aplicación:

@NgModule({
  declarations: [AppComponent, NxWelcomeComponent],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    NbLayoutModule,
    LoginComponentModule,
    AppRoutingModule,
    NbThemeModule.forRoot({ name: 'default' }),
    NbLayoutModule,
    NbEvaIconsModule,
  ],
  providers: [AuthGuard],
  bootstrap: [AppComponent],
})
export class AppModule {}

Módulo de enrutamiento de la aplicación:

const routes: Routes = [
  {path: 'dashboard' , component: DashboardComponent, canActivate: [AuthGuard]},
  {path: 'authenticate', component: LoginComponent},
  {path: '' , redirectTo: 'authenticate', pathMatch: 'full'}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: [AuthGuard]
})
export class AppRoutingModule {

}

Respuesta #1

Necesitas ir al panel después de iniciar sesión:

Las rutas:

const routes: Routes = [
  {
    path: 'dashboard',
    component: DashboardComponent,
    canActivate: [AuthGuard],
  },
  { path: '', redirectTo: 'authenticate', pathMatch: 'full' },
];

El Componente:

export class AppComponent {
  constructor(
    private authService: AuthenticationService,
    private router: Router
  ) {}

  callServiceMethod(value: string) {
    // This will need to wait for auth to finish before navigating in the actual app.
    this.authService.authenticateUser(value);
    if (this.authService.isAuthenticated) {
      this.router.navigate(['dashboard']);
    }
  }
}

El guardia:

@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
  constructor(private auth: AuthenticationService, private router: Router) {}

  canActivate(): Promise<boolean> {
    return new Promise((resolve) => {
      console.log('running auth guard!');
      if (this.auth.isUserLoggedIn()) {
        resolve(true);
      } else {
        this.router.navigate(['authenticate']);
        resolve(false);
      }
    });
  }
}

Aquí hay un ejemplo actualizado:

https://stackblitz.com/edit/angular-ivy-5excpc?file=src%2Fapp%2Fapp.component.ts

Respuesta #2

Tu canActivate solo debería tomar tu clase AuthGuard que tiene el resolvedor.

{path: 'dashboard' , component: DashboardComponent, canActivate: [AuthGuard]}