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

175 lines
3.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
```json
{
"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**
```json
{
"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
```json
{ "error": "E-mail já cadastrado." }
```
**422 Unprocessable Entity** — falha de validação Pydantic
```json
{
"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
```json
{
"email": "joao@exemplo.com",
"password": "minhasenha123"
}
```
| Campo | Tipo | Obrigatório |
|-------|------|-------------|
| `email` | string (email válido) | ✅ |
| `password` | string | ✅ |
### Respostas
**200 OK**
```json
{
"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)
```json
{ "error": "Credenciais inválidas." }
```
**422 Unprocessable Entity** — falha de validação Pydantic
```json
{ "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**
```json
{
"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
```json
{ "error": "Token de acesso inválido ou expirado." }
```
---
## JWT Payload
```json
{
"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:
```json
{ "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)