Pular para o conteúdo
← Projetos

Backend

E-commerce API

Catálogo aberto para leitura e fechado para escrita. Login com JWT, senha com BCrypt, upload de imagem e Swagger gerado do código.

9endpoints · 4 exigem JWT

O problema

Qualquer pessoa pode olhar o catálogo, mas só quem tem conta pode mexer nele. O jeito fácil seria guardar sessão na memória do servidor, e aí a API só funciona enquanto roda numa máquina só. Eu queria resolver do jeito que aguenta crescer.

Arquitetura

Um OncePerRequestFilter valida o JWT (jjwt, HS256) e popula o SecurityContext antes de a requisição chegar ao controller. As senhas são gravadas com BCrypt. O SecurityFilterChain libera GET público e exige token na escrita. O upload é multipart com validação de tipo e proteção contra path traversal. O springdoc gera o Swagger UI a partir das anotações.

O contrato

Copiei do controller. É isto que a API responde.

POST/api/auth/login200 OK

Envio

{
  "email": "ana@exemplo.com",
  "senha": "senha-forte-aqui"
}

Resposta

{
  "token": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhbmFAZXhlbXBsby5jb20i...",
  "tipo": "Bearer",
  "expiraEmSegundos": 3600
}

O token já vem com a validade dele na resposta.

POST/api/produtos400 Bad Request

Authorization: Bearer <token>

Envio

{
  "nome": "",
  "preco": -10
}

Resposta

{
  "type": "about:blank",
  "title": "Erro de validação",
  "status": 400,
  "detail": "Um ou mais campos são inválidos",
  "erros": {
    "nome": "nome é obrigatório",
    "preco": "preco deve ser maior que zero",
    "estoque": "estoque é obrigatório"
  }
}

Quando a validação falha, a resposta diz qual campo e por quê.

Decisões

  1. 01

    Stateless em vez de sessão

    O servidor não lembra de ninguém. Quem prova quem é, a cada chamada, é o token.

  2. 02

    Permissão por método e rota

    Deixei toda a regra de acesso no SecurityFilterChain. Assim eu abro um arquivo e vejo o que está protegido, em vez de caçar if em cinco controllers.

  3. 03

    Upload tratado como entrada hostil

    Valido o tipo e limpo o nome do arquivo antes de gravar. Upload é o lugar mais fácil de alguém enfiar ../.. no caminho e sair lendo o disco.

O que ficou de pé

  • 6 testes de integração cobrindo registro, login, acesso protegido e caminhos de erro
  • Swagger UI publicado a partir do próprio código, sem documentação paralela para envelhecer
  • Ambiente reprodutível via Docker