Skip to content

eriksonwilliam/auth-service

Repository files navigation

auth-service

Serviço de autenticação e autorização em Go (só stdlib + x/crypto): JWT HS256 escrito à mão, senhas com bcrypt, RBAC (papéis → permissões) e rotação de refresh token com detecção de reuso. Arquitetura hexagonal e cobertura de testes 100%.

POST /register ─▶ cria usuário (senha em bcrypt)
POST /login    ─▶ access token (15min) + refresh token (24h)
GET  /me       ─▶ exige permissão me:read      (Bearer)
GET  /admin    ─▶ exige permissão admin:access (Bearer)
POST /refresh  ─▶ rotaciona: emite novo par e revoga o antigo

Destaques

  • JWT HS256 à mão — assinar/verificar sobre a stdlib (crypto/hmac, crypto/sha256), para mostrar o que um JWT realmente é. A verificação checa o algoritmo (barra o ataque alg:none) e compara a assinatura em tempo constante (hmac.Equal).
  • RBAC — papéis (user, admin) concedem permissões (me:read, admin:access); os endpoints exigem uma permissão, não um papel fixo.
  • Rotação de refresh token — cada refresh emite um par novo e revoga o anterior; reusar um refresh já usado é rejeitado (detecção de reuso).
  • Senhas com bcrypt — nunca em texto; o hashing fica atrás de uma porta (Hasher), então os testes de caso de uso rodam rápido com um fake.
  • Arquitetura hexagonal — domínio (usuário, RBAC, validação) → aplicação (AuthService + ports) → infraestrutura (repos em memória, bcrypt, HTTP).
  • Cobertura 100% — inclusive os caminhos de erro do JWT (assinatura adulterada, alg inválido, expiração) e do RBAC (403).
  • OpenAPI/Swagger em /docs.

Stack

  • Linguagem: Go 1.25 (stdlib + golang.org/x/crypto/bcrypt)
  • Tokens: JWT HS256 próprio · Autz: RBAC
  • Testes/cobertura: go test -cover (gate de 100%)

Arquitetura

cmd/api/                     # bootstrap (semeia um admin de exemplo)
internal/
├── token/                   # JWT HS256 (sign/verify) — sem libs externas
├── domain/                  # User, RBAC (papéis→permissões), validação, erros
├── application/             # AuthService + ports (UserRepo, RefreshStore, Hasher)
└── infrastructure/
    ├── memory/              # repositórios em memória
    ├── security/            # BcryptHasher
    └── httpapi/             # rotas, DTOs, Swagger

Como rodar

go run ./cmd/api      # http://localhost:8080  (Swagger em /docs)

Fluxo completo:

curl -X POST localhost:8080/register -H "content-type: application/json" \
  -d '{"email":"ada@example.com","password":"senha-forte-123"}'

TOKENS=$(curl -s -X POST localhost:8080/login -H "content-type: application/json" \
  -d '{"email":"ada@example.com","password":"senha-forte-123"}')

ACCESS=$(echo "$TOKENS" | jq -r .accessToken)
curl localhost:8080/me -H "Authorization: Bearer $ACCESS"

Um usuário admin (admin@example.com / admin-123456) é semeado para você testar o /admin. Configure via ADMIN_EMAIL, ADMIN_PASSWORD e JWT_SECRET.

Docker

docker compose up --build

Endpoints

Método Rota Protegido Descrição
POST /register Cria usuário (papel user)
POST /login Emite access + refresh token
POST /refresh Rotaciona o refresh token
GET /me Bearer Perfil (permissão me:read)
GET /admin Bearer Área admin (permissão admin:access)
GET /docs Swagger UI

Segurança — decisões

  • alg:none é rejeitado: a verificação exige alg == HS256.
  • Comparação da assinatura em tempo constante (hmac.Equal) — evita timing.
  • Refresh rotation: um refresh só vale uma vez; o próximo uso é negado.
  • Segredo, TTLs e credenciais do admin vêm de ambiente — nada hardcoded em prod.

Nota: este é um template de referência. Em produção, use um segredo forte (ou chaves assimétricas), persistência real e HTTPS na borda.

Testes e cobertura

go test ./internal/... -covermode=atomic -coverprofile=coverage.out
go tool cover -func=coverage.out        # total: 100.0%

Licença

MIT.

About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors