Autenticação e Provedor de Identidade
Pilar: 01 — Arquitetura, Stack e Segurança
Status: 🟢 Implementado
Última Revisão Técnica: 2026-08-03
Módulos Conectados:gatein-server(app/core/security.py,app/api/mobile/auth.py,app/api/web/auth.py),gatein-app(src/context/AuthContext),gatein-web(src/context/AuthContext)
1. Visão Geral da Arquitetura de Identidade
O ecossistema Gatein utiliza um modelo híbrido de autenticação de alta segurança para suportar dois perfis de usuários com requisitos distintos:
- Motoristas (Mobile App): Autenticação baseada em CPF/Tax ID, validação de dispositivo confiável (
validated_device), verificação de OTP de 4 dígitos via Redis com expiração de 5 minutos, e geração de token JWT customizado assinado pelo servidor. - Operadores de Terminal / Transportadores (Web App): Autenticação baseada em e-mail e senha via Firebase Auth, convertida no servidor através do Firebase Admin SDK para verificação de ID Tokens Bearer.
1.1 Diagrama de Fluxo de Autenticação Híbrida
sequenceDiagram
autonumber
actor M as Motorista (Mobile)
actor W as Operador Web
participant S as Gatein Server (FastAPI)
participant R as Redis (OTP Storage)
participant FB as Firebase Auth SDK
participant DB as PostgreSQL
rect rgb(20, 30, 45)
note over M, S: Fluxo Mobile (CPF + OTP / Staging + JWT)
M->>S: POST /mobile/auth/check-status (tax_id)
S->>DB: Verifica status do cadastro (new / registered)
M->>S: POST /mobile/auth/otp/send (tax_id, phone)
S->>R: Grava otp:{tax_id} (code: 4 digitos, TTL: 300s)
M->>S: POST /mobile/auth/login (tax_id, password, device)
S->>DB: Valida password_hash (ou StagingPassword em dev/staging)
S->>DB: Confirma se validated_device == device
S-->>M: Retorna JWT Bearer Token + User Data
end
rect rgb(35, 25, 45)
note over W, FB: Fluxo Web (Firebase Auth + Bearer Token)
W->>FB: signInWithEmailAndPassword(email, password)
FB-->>W: Retorna Firebase ID Token (JWT expira 1h)
W->>S: Request com Header Authorization: Bearer <Firebase_ID_Token>
S->>FB: firebase_admin.auth.verify_id_token(token)
S->>DB: Carrega CompanyUser por email/uid + company_id
S-->>W: Acesso autorizado (Contexto Tenant Injetado)
end
2. Autenticação Mobile (App do Motorista)
2.1 Estrutura do Token JWT Customizado
Para o aplicativo mobile, o servidor gera tokens JWT próprios utilizando o segredo configurado no servidor (settings.JWT_SECRET_KEY).
Payload do Token JWT Mobile:
{
"sub": "b8f219c4-1234-4567-89ab-cdef01234567",
"tax_id": "12345678901",
"device_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"exp": 1785891100,
"iat": 1785804700
}
2.2 Estrutura do OTP no Redis
Os códigos de verificação OTP gerados para o motorista são salvos no Redis com chave formatada e tempo de expiração estrito:
- Chave:
otp:{tax_id} - TTL:
300 segundos(5 minutos) - Conteúdo (JSON):
{"code": 4821, "phone": "+5511999998888"}
2.3 Suporte a Senhas de Homologação / Staging (StagingPassword)
Em ambientes de desenvolvimento ou staging (settings.should_use_staging_logic == True), se o hash da senha padrão do usuário falhar na comparação, o backend consulta a tabela staging_passwords.
- Se a senha fornecida corresponder a uma senha de staging ativa, o login é aprovado.
- Isenção de Validação de Dispositivo: Quando o login é efetuado via
StagingPassword, a exigência deuser.validated_device == body.deviceé contornada (is_staging_password = True), permitindo testes automatizados e homologação em múltiplos dispositivos sem travar o motorista.
3. Autenticação Web (Painel de Terminais e Transportadores)
3.1 Verificação de ID Token com Firebase Admin SDK
Toda requisição feita ao servidor a partir do Web App inclui o header:
Authorization: Bearer <Firebase_ID_Token>
No backend, a dependência get_current_admin_company_user executa a validação:
decoded_token = firebase_admin.auth.verify_id_token(token)- Extrai
email = decoded_token['email']ouuid = decoded_token['uid']. - Consulta no PostgreSQL:
CompanyUserfiltrando poremaileis_active == True. - Garante a injeção do
company_idpara isolamento de Tenant Guard em todos os endpoints operacionais.
4. Regras de Negócio Explícitas (RN-AUTH-XXX)
RN-AUTH-001: Formatação e Validação de Dígitos Verificadores do CPF
O campo tax_id deve ser obrigatoriamente sanitizado (remoção de pontos e traços) no client e no server. O servidor rejeitará com HTTP 400 (TAX_ID_INVALID) qualquer requisição cujo CPF não atenda ao algoritmo oficial de dígitos verificadores (Módulo 11).
RN-AUTH-002: Expiração e Invalidação Única do OTP
O código OTP possui vida útil máxima de 300 segundos no Redis. Após uma tentativa de verificação bem-sucedida no endpoint /mobile/auth/otp/verify, a chave otp:{tax_id} é imediatamente deletada do Redis, impedindo reutilização do mesmo código (replay attack).
RN-AUTH-003: Restrição de Dispositivo Confiável (validated_device)
No fluxo de produção, o motorista só pode autenticar a partir do dispositivo cujo identificador único coincida com user.validated_device. Se o motorista tentar logar a partir de outro dispositivo, a API retorna HTTP 403 (DEVICE_NOT_VALIDATED), exigindo que o motorista refaça a validação de CNH/SMS para autorizar o novo aparelho.
RN-AUTH-004: Lógica de Bypass de Homologação em Produção
A tabela staging_passwords e qualquer lógica de bypass de OTP são completamente desativadas e ignoradas em ambiente de produção (ENVIRONMENT == 'production'). Qualquer tentativa de passar credenciais de staging em produção resultará em HTTP 401 (PASSWORD_INVALID).
RN-AUTH-005: Atualização Obrigatoria de FCM Token no Login
A cada login realizado com sucesso pelo aplicativo mobile, o cliente enviará o FCM Token do dispositivo via POST /mobile/auth/register-fcm-token. O servidor associará o token ao registro do motorista e revogará o token anterior para evitar o envio de notificações de agendamentos/check-in para o dispositivo incorreto.
RN-AUTH-006: Revogação e Desativação de Usuários Web
Quando um CompanyUser tem o campo is_active alterado para False, todas as tentativas subsequentes de consumo da API usando seu token Firebase retornarão HTTP 403 (USER_DEACTIVATED), ignorando a validade restante do ID Token de 1 hora do Firebase.
5. Matriz de Erros de Autenticação
| Código HTTP | Código da Resposta JSON | Causa Técnica | Ação Recomendada no Cliente |
|---|---|---|---|
400 Bad Request | OTP_EXPIRED | Chave otp:{tax_id} não encontrada no Redis | Exibir botão de reenvio de OTP |
400 Bad Request | TAX_ID_AND_PHONE_MISMATCH | Telefone enviado difere do cadastrado na requisição OTP | Pedir confirmação do número de telefone |
400 Bad Request | PHONE_VALIDATION_CODE_INVALID | Código OTP digitado não confere | Exibir mensagem "Código inválido. Tente novamente" |
401 Unauthorized | PASSWORD_INVALID | Hash de senha incorreto (e sem match em staging) | Destacar campo de senha com erro |
403 Forbidden | DEVICE_NOT_VALIDATED | Dispositivo difere de validated_device | Redirecionar para tela de validação de CNH/Dispositivo |
404 Not Found | USER_NOT_FOUND | CPF não localizado na tabela users | Redirecionar para o fluxo de onboarding (/check-status) |