Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

gRPC Interceptors: autenticação e logs no Node.js

Atualizado em: 28 de outubro de 2026

Terminal Linux usado em desenvolvimento e administração de aplicações Node.js

gRPC Interceptors no Node.js permitem executar lógica transversal ao redor das chamadas, como autenticação, logs, tracing, métricas, retries e enriquecimento de metadata. Eles evitam repetir o mesmo código em cada método do serviço.

Um interceptor deve ser pequeno, previsível e independente da regra de negócio. Ele não deve esconder fluxos complexos nem transformar todos os erros em um único status.

Interceptors no cliente

O cliente pode anexar um interceptor às opções do canal ou da chamada. Um interceptor recebe informações do método e cria uma chamada delegando ao próximo elemento da cadeia.

function loggingInterceptor(options, nextCall) {
  const requester = {
    start(metadata, listener, next) {
      const startedAt = performance.now();

      const wrappedListener = {
        onReceiveStatus(status, nextStatus) {
          const duration = performance.now() - startedAt;
          logger.info({
            method: options.method_definition.path,
            code: status.code,
            duration
          });
          nextStatus(status);
        }
      };

      next(metadata, wrappedListener);
    }
  };

  return new grpc.InterceptingCall(nextCall(options), requester);
}

Configurando no cliente

const client = new CatalogService(address, credentials, {
  interceptors: [loggingInterceptor, tracingInterceptor]
});

A ordem importa. Um interceptor externo observa todos os internos. Documente a sequência.

Adicionando metadata

function authInterceptor(options, nextCall) {
  return new grpc.InterceptingCall(nextCall(options), {
    start(metadata, listener, next) {
      metadata.set('authorization', `Bearer ${tokenProvider.get()}`);
      metadata.set('x-request-id', crypto.randomUUID());
      next(metadata, listener);
    }
  });
}

Não registre a metadata completa, pois pode conter tokens e dados sensíveis.

Tracing

O interceptor pode criar um span por RPC e injetar o contexto:

const span = tracer.startSpan(options.method_definition.path);
propagation.inject(context.active(), metadataCarrier);

Finalize o span com status, duração e erro seguro. Preserve o trace recebido ao chamar serviços downstream.

Retries no interceptor

Retries centralizados são tentadores, mas precisam respeitar idempotência, status e deadline. Não repita automaticamente todos os métodos.

  • permita apenas métodos aprovados;
  • repita códigos transitórios;
  • use backoff com jitter;
  • pare quando o deadline não comportar outra tentativa;
  • registre número da tentativa.

Credenciais por chamada

Quando o token varia por usuário, obtenha-o no contexto da requisição, não em variável global compartilhada. Em workers, use identidade técnica explícita.

Interceptors no servidor

O suporte e a forma de interceptação no servidor dependem da versão da biblioteca. Uma alternativa estável é envolver handlers durante o registro:

function withAuth(handler) {
  return async function wrapped(call, callback) {
    try {
      call.auth = await authenticate(call.metadata);
      authorize(call.auth, call.request);
      return handler(call, callback);
    } catch (error) {
      callback(toGrpcError(error));
    }
  };
}
server.addService(service, {
  getProduct: withMetrics(withAuth(getProduct))
});

Centralize a composição para que nenhum método esqueça autenticação.

Contexto por chamada

Crie um objeto imutável com identidade, tenant, request ID, deadline e logger contextual:

call.context = Object.freeze({
  requestId,
  tenantId,
  subject,
  deadline: call.getDeadline()
});

Não permita que o payload altere o tenant já autenticado.

Validação de metadata

Limite quantidade e tamanho. Rejeite chaves inesperadas quando o protocolo for restrito. Metadata binária usa convenções específicas e não deve ser convertida sem validação.

Mapeamento de erros

function toGrpcError(error) {
  if (error instanceof ValidationError) {
    return { code: grpc.status.INVALID_ARGUMENT, message: error.publicMessage };
  }

  if (error instanceof ForbiddenError) {
    return { code: grpc.status.PERMISSION_DENIED, message: 'Acesso negado' };
  }

  logger.error({ error }, 'unhandled grpc error');
  return { code: grpc.status.INTERNAL, message: 'Erro interno' };
}

Um wrapper pode garantir tradução consistente sem ocultar erros conhecidos.

Métricas

Registre contadores e histogramas por serviço, método e status. Não use request ID ou usuário como label.

grpcDuration.observe(
  { service, method, code },
  durationSeconds
);

Logging

Um interceptor pode emitir log inicial e final. Evite registrar payloads por padrão; mensagens podem conter dados pessoais ou segredos.

Rate limiting

Rate limiting pode usar identidade e método. A decisão deve ocorrer antes da regra de negócio e retornar RESOURCE_EXHAUSTED. Em múltiplas instâncias, use armazenamento compartilhado quando necessário.

Interceptors e streaming

Streaming exige observar eventos de dados, encerramento e cancelamento. Não armazene todos os chunks para logar ou medir. Conte bytes e mensagens incrementalmente.

Backpressure

Um interceptor de transformação não deve ignorar o fluxo do stream. Processamento pesado deve respeitar pause, resume e sinais de drenagem.

Deadlines

Leia o deadline no início e inclua o tempo restante no contexto. Interceptors de retry e autenticação precisam consumir o mesmo orçamento.

Consulte gRPC Deadlines no Node.js.

Ordem recomendada

Uma cadeia possível:

  1. request ID;
  2. tracing;
  3. métricas;
  4. autenticação;
  5. rate limiting;
  6. validação;
  7. handler;
  8. mapeamento de erro.

A ordem exata depende de quais falhas precisam ser medidas e auditadas.

Falhas no interceptor

Qualquer interceptor pode impedir a chamada. Capture erros próprios e retorne status coerente. Não deixe exceções assíncronas escaparem de callbacks.

Testes unitários

Teste o interceptor com uma chamada falsa:

  • metadata adicionada;
  • token ausente;
  • status preservado;
  • span finalizado;
  • deadline respeitada;
  • retry apenas em método permitido;
  • payload não registrado.

Testes de integração

Suba cliente e servidor reais e confirme que a cadeia funciona com TLS, streaming, cancelamento e erros.

Observabilidade do próprio interceptor

Meça falhas de autenticação, tempo gasto antes do handler e erros na instrumentação. Um interceptor lento afeta todos os métodos.

Erros comuns

  • interceptor com regra de negócio;
  • ordem não documentada;
  • logar metadata sensível;
  • retry genérico;
  • token global entre usuários;
  • engolir status original;
  • ignorar streaming;
  • labels de alta cardinalidade;
  • instrumentação que lança erro.

Conclusão

gRPC Interceptors no Node.js centralizam preocupações transversais sem poluir handlers. Eles funcionam melhor quando cada componente tem uma responsabilidade clara e a ordem de execução é explícita.

Use interceptors para contexto, autenticação, métricas e tracing, mas preserve deadlines, streaming e status codes. Teste a cadeia completa para garantir que instrumentação e retries não alteram a semântica da API.

Consulte a documentação oficial de interceptors do gRPC e a referência de client interceptors do grpc-node.

10 melhores cursos de programação em 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita