1
resposta

Problemas com autenticação

Estou criando autenticação com o angular e estou com problemas de permissão. Já verifiquei pelo backend e consigo acessar perfeitamente após a realização do login. Já no front recebo: ' GET http://localhost:4200/licencas 403 (Forbidden)'. No backend estou usando spring security com token jwt.

minhas rotas:

  {
    path: 'login',
    component: LoginFormComponent,
  },
  {
    path: 'home',
    component: HomeComponent,
    canActivate: [ AuthGuardService ]
  },
  {
    path: 'licencas',
    component: ListLicencasComponent,
    canActivate: [ AuthGuardService ],
  },
  {
    path: 'nova-licenca',
    component: CrudLicencasComponent,
    canActivate: [ AuthGuardService ],
  },
  {
    path: 'editar-licenca/:id',
    component: CrudLicencasComponent,
    canActivate: [ AuthGuardService ]
  },
  {
    path: 'excluir-licenca/:id',
    component: CrudLicencasComponent,
    canActivate: [ AuthGuardService ]
  },
  {
    path: 'licencas/monitor',
    component: MonitorPageComponent,
    canActivate: [ AuthGuardService ],
  },
  {
    path: 'licencas/enviarEmailNotificacao/:id',
    component: MonitorComponentComponent,
    canActivate: [ AuthGuardService ]
  },
  {
    path: 'usuarios',
    component: ListUsuariosComponent,
    canActivate: [ AuthGuardService ]
  },
  {
    path: 'novo-usuario',
    component: CrudUsuariosComponent,
    canActivate: [ AuthGuardService ]
  },
  {
    path: 'editar-usuario/:id',
    component: CrudUsuariosComponent,
    canActivate: [ AuthGuardService ]
  },
  {
    path: 'excluir-usuario/:id',
    component: CrudUsuariosComponent,
    canActivate: [ AuthGuardService ]
  },
  {
    path: '**',
    redirectTo: 'login'
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes, { useHash: true }), DxDataGridModule, DxFormModule],
  providers: [AuthGuardService],
  exports: [RouterModule],
  declarations: []
})
export class AppRoutingModule { }

authservice:

export class AuthService {

  private readonly API = 'login';

  private currentUser: Usuarios | null = null;


  constructor(private http: HttpClient, private router: Router) { }

  login(email: string, senha: string): Observable<Usuarios> {
    return this.http.post<Usuarios>(`${this.API}`, { email: email, senha: senha }).pipe(
      tap(response => {
        this.setCurrentUser(response);
        localStorage.setItem('token', response.token);
      })
    );
  }

  getRole() {
    const token = localStorage.getItem('token');
    if (token) {
      const tokenPayload = JSON.parse(atob(token.split('.')[1]));
      console.log('Role: ', tokenPayload);

      return tokenPayload.roles;
    }

    return null;
  }

  async logOut() {
    this.currentUser = null;
    localStorage.removeItem('token');
    this.router.navigate(['/login']);
  }

  setCurrentUser(user: Usuarios): void {
    this.currentUser = user;
  }

  getCurrentUser(): Usuarios | null {
    return this.currentUser;
  }

  isLoggedIn(): boolean {
    return !!this.getCurrentUser();
  }

  isAdmin(): boolean {
    const userRoles = this.getRole();
    const isAdmin = !!((userRoles && (userRoles.includes('ROLE_ADMIN'.trim()) || userRoles.includes('ROLE_USER'.trim()))) ?? false);

    return isAdmin;
  }

}

guard:

export class AuthGuardService implements CanActivate {
  constructor(private router: Router, private authService: AuthService) {}


  canActivate(): boolean {
    if (this.authService.isLoggedIn() && this.authService.isAdmin()) {
      return true;
    } else {
      this.router.navigate(['/login']);
      return false;
    }
  }
}

e por fim meu login component:


  loading = false;

  formData: any = {};

  constructor(private authService: AuthService, private router: Router) { }

  async onSubmit(e: Event) {
    e.preventDefault();
    const { email, senha } = this.formData;
    this.loading = true;

    try {
      const user = await this.authService.login(email, senha).toPromise();
      if (user && user.token) {
        notify('Login efetuado com sucesso', 'success', 2000);
        this.router.navigate(['/home']);
      } else {
        notify('Credenciais inválidas', 'error', 4000);
      }
    } catch (error) {
      notify('Erro ao processar a solicitação', 'error', 4000);
    } finally {
      this.loading = false;
    }
  }
}

Não consegui encontrar onde esta meu problema.

1 resposta

Olá, Natali. Tudo bem?

Pelo que pude analisar no código que você compartilhou, parece que você está fazendo a autenticação corretamente e o token JWT está sendo armazenado no localStorage. No entanto, o erro 403 (Forbidden) indica que o servidor entendeu a requisição, mas se recusa a autorizá-la. Isso geralmente ocorre porque o token não está sendo enviado no header da requisição para o endpoint '/licencas'.

No seu serviço de autenticação, você está armazenando o token no localStorage, mas não vi no seu código onde você está adicionando esse token ao header das suas requisições HTTP(você não compartilhou essa parte).

Você precisa adicionar o token JWT ao header das suas requisições. Para fazer isso, você pode criar um interceptor HTTP. Aqui está um exemplo de como você pode fazer isso:

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class JwtInterceptor implements HttpInterceptor {

  constructor() {}

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    let token = localStorage.getItem('token');

    if (token) {
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${token}`
        }
      });
    }

    return next.handle(request);
  }
}

Depois de criar o interceptor, você precisa adicioná-lo à lista de provedores no seu módulo principal (geralmente AppModule):

import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { JwtInterceptor } from './_helpers/jwt.interceptor';

@NgModule({
  ...
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
    ...
  ],
  ...
})
export class AppModule { }

Espero que isso possa resolver o seu problema. Lembre-se de que é apenas uma sugestão baseada no código que você compartilhou e pode haver outros fatores em seu projeto que estão causando o problema. Qualquer coisa compartilha mais detalhes aqui com a gente.

Bons estudos!