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]}
