sass-imobiliaria/.specify/features/005-authentication/contracts/auth-api.md

3.6 KiB
Raw Blame History

API Contract: Auth Endpoints

Prefixo: /api/v1/auth Blueprint: auth_bp em backend/app/routes/auth.py Content-Type: application/json Autenticação: Bearer token via header Authorization (onde indicado)


POST /api/v1/auth/register

Cria uma nova conta de cliente. Token de acesso emitido imediatamente na resposta.

Request Body

{
  "name": "João Silva",
  "email": "joao@exemplo.com",
  "password": "minhasenha123"
}
Campo Tipo Obrigatório Regras
name string 1150 caracteres
email string (RFC 5321) Email válido; normalizado para lowercase antes de persistir
password string Mínimo 8 caracteres

Respostas

201 Created

{
  "access_token": "<jwt_string>",
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "João Silva",
    "email": "joao@exemplo.com",
    "role": "client",
    "created_at": "2026-04-13T15:00:00"
  }
}

409 Conflict — e-mail já cadastrado

{ "error": "E-mail já cadastrado." }

422 Unprocessable Entity — falha de validação Pydantic

{
  "error": "Dados inválidos.",
  "details": [
    { "loc": ["body", "password"], "msg": "String should have at least 8 characters", "type": "string_too_short" }
  ]
}

POST /api/v1/auth/login

Autentica um cliente existente e emite token de acesso.

Request Body

{
  "email": "joao@exemplo.com",
  "password": "minhasenha123"
}
Campo Tipo Obrigatório
email string (email válido)
password string

Respostas

200 OK

{
  "access_token": "<jwt_string>",
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "João Silva",
    "email": "joao@exemplo.com",
    "role": "client",
    "created_at": "2026-04-13T15:00:00"
  }
}

401 Unauthorized — e-mail não encontrado ou senha incorreta (mesma resposta para não revelar qual campo falhou — FR-007, SC-006)

{ "error": "Credenciais inválidas." }

422 Unprocessable Entity — falha de validação Pydantic

{ "error": "Dados inválidos.", "details": [...] }

GET /api/v1/auth/me

Retorna dados do usuário autenticado. Requer Authorization: Bearer <token>.

Headers

Authorization: Bearer <jwt_string>

Respostas

200 OK

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "João Silva",
  "email": "joao@exemplo.com",
  "role": "client",
  "created_at": "2026-04-13T15:00:00"
}

401 Unauthorized — sem token, token inválido ou token expirado

{ "error": "Token de acesso inválido ou expirado." }

JWT Payload

{
  "sub": "<uuid-string do ClientUser>",
  "exp": <unix timestamp  now() + 7 dias>
}
Campo Valor
Algorithm HS256
Secret JWT_SECRET_KEY (variável de ambiente)
TTL 7 dias (604800 s)
Claim sub UUID do ClientUser como string

Envelope de Erro Padrão

Todas as respostas de erro seguem o envelope:

{ "error": "<mensagem legível>" }

Erros de validação 422 incluem details com a lista de erros Pydantic. Respostas de erro nunca incluem informações que permitam distinguir e-mail vs. senha incorretos (SC-006).


Notas de Segurança

  • Nenhuma resposta inclui password_hash
  • 401 em credenciais inválidas NÃO DEVE indicar qual campo está incorreto
  • JWT_SECRET_KEY NUNCA deve aparecer em logs ou respostas da API
  • CORS configurado explicitamente em create_app() (sem wildcard em produção)