Introdução aos Interceptores HTTP no Angular
Os interceptores HTTP no Angular oferecem uma ferramenta poderosa para inspecionar e transformar requisições e respostas HTTP antes que sejam processadas pelos componentes da aplicação. Esta funcionalidade é extremamente útil para implementra lógica global, como adicionar cabeçalhos de autenticação, exibir indicadores de carregamento, registrar erros ou manipular respostas de forma centralizada.
A partir do Angular 17.3 (ou versões posterioers que utilizam o conceito de interceptores), a integração é feita de maneira robusta, permitindo que a aplicação adicione funcionalidades de infraestrutura em todas as comunicações com a API de forma transparente.
Passo 1: Criando um Serviço de Interceptor
Primeiro, crie o serviço do interceptor usando o Angular CLI. Este serviço implementará a interface HttpInterceptor.
ng generate service services/auth-token.interceptor
Em seguida, edite o arquivo gerado (auth-token.interceptor.ts) para incluir a lógica de interceptação. No exemplo abaixo, o interceptor adiciona um cabeçalho Authorization se um token estiver disponível no localStorage e ainda não existir na requisição.
import { Injectable } from '@angular/core';
import { HttpResponse, HttpRequest, HttpInterceptor, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable, tap } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AuthTokenInterceptor implements HttpInterceptor {
constructor() { }
intercept(request: HttpRequest<any>, handler: HttpHandler): Observable<HttpEvent<any>> {
let modifiedRequest = request;
const storedToken = localStorage.getItem('userToken'); // Recupera o token de uma chave específica
// Verifica se há um token e se o cabeçalho Authorization já não está presente
if (storedToken && !request.headers.has('Authorization')) {
console.log('AuthTokenInterceptor: Adicionando cabeçalho de autenticação à requisição.');
modifiedRequest = request.clone({
setHeaders: {
Authorization: `Bearer ${storedToken}` // Adiciona o token como um Bearer
}
});
} else if (request.headers.has('Authorization')) {
console.log('AuthTokenInterceptor: Cabeçalho de autenticação já presente na requisição.');
} else {
console.log('AuthTokenInterceptor: Nenhum token para adicionar ou já existente.');
}
// Continua com a requisição e observa a resposta
return handler.handle(modifiedRequest).pipe(
tap({
next: (event) => {
if (event instanceof HttpResponse) {
console.log('AuthTokenInterceptor: Resposta HTTP recebida com status:', event.status);
// Lógica adicional para respostas bem-sucedidas pode ser implementada aqui
}
},
error: (error) => {
console.error('AuthTokenInterceptor: Erro na requisição HTTP:', error.status, error.message);
// Lógica centralizada para tratamento de erros
}
})
);
}
}
Passo 2: Registrando o Interceptor no Módulo Raiz (AppModule)
Para que o interceptor seja utilizado por toda a aplicação, ele precisa ser configurado no arquivo app.module.ts. É fundamental importá-lo e adicioná-lo ao array de providers usendo o token HTTP_INTERCEPTORS.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule, HTTP_INTERCEPTORS, HttpClient } from '@angular/common/http'; // Importações essenciais
// Importe o seu serviço de interceptor
import { AuthTokenInterceptor } from './services/auth-token.interceptor';
// Outras importações de componentes e módulos (omitidas para brevidade)
// ...
@NgModule({
declarations: [
AppComponent,
// ... outros componentes ...
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule, // Necessário para o HttpClient e interceptores
// ... outros módulos ...
],
providers: [
{
provide: HTTP_INTERCEPTORS, // Token para o qual o interceptor será injetado
useClass: AuthTokenInterceptor, // A classe do seu interceptor
multi: true // Permite que múltiplos interceptores sejam registrados
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
Passo 3: Testando o Interceptor em um Componente
Após a configuração, qualquer requisição HTTP feita usando o HttpClient será automaticamente interceptada. Para testar, você pode criar um componente que faça uma requisição simples. Certifique-se de definir um token no localStorage para que o interceptor possa adicioná-lo.
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-student',
templateUrl: './student.component.html',
styleUrls: ['./student.component.scss']
})
export class StudentComponent implements OnInit {
fetchedUserName: string = '';
constructor(private httpService: HttpClient) { }
ngOnInit(): void {
// Simula a definição de um token no localStorage para o interceptor usar
localStorage.setItem('userToken', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvbmggRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c');
// Faz uma requisição HTTP para um endpoint fictício
this.httpService.get<any>('http://localhost:4200/api/profile/details').subscribe({
next: (response) => {
console.log('Componente: Dados do perfil recebidos:', response);
this.fetchedUserName = response.name || 'Nome Não Disponível';
},
error: (error) => {
console.error('Componente: Erro ao carregar perfil:', error);
this.fetchedUserName = 'Erro ao carregar dados do perfil';
}
});
}
}
O template HTML (student.component.html) para exibir os dados seria simples:
<h2>Detalhes do Estudante</h2>
<p>Status da Requisição: Carregando...</p>
<p>Nome do Usuário Retornado: <strong>{{ fetchedUserName }}</strong></p>
Ao executar a aplicação e acessar o componente StudentComponent, você verá os logs do interceptor no console do navegador, indicando que o cabeçalho de autenticação foi adicionado à requisição antes de ela ser enviada ao servidor.