Pular para conteúdo

Configurar login Google das views

Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-07-06

O que é

Habilita o login Google (Firebase) nas views server-rendered (/processamentos/**, /admin/**), restrito a emails @xadm.com.br. O desenho está na etapa 06 e na decisão 0003; aqui é o procedimento de configuração.

  • Client: Firebase Authentication (Google sign-in) — popup do Google no navegador.
  • Servidor: valida o ID token do Firebase (RS256, contra o JWKS público do Google via nimbus-jose-jwt) e emite um cookie de sessão próprio (xadm_session, JWT HS256, TTL 8 h).
  • Gate: a regra de segurança das views exige o cookie em todo path fora da whitelist (dentro do micronaut-security, sem filtro paralelo).

O /api/** (Bearer) não é afetado — a regra das views faz whitelist de /api/** (decisão 0002).

Quando usar

  • Subir um ambiente de produção (as views precisam das envs AUTH_*, senão ficam fail-closed em 503).
  • Apontar o app para um novo domínio público (precisa autorizar o domínio no Firebase).

Pré-requisitos no Firebase (infra, fora do código)

Reusa o projeto Firebase existente xadm-6ab81 (compartilhado entre apps X-Adm). Antes do deploy:

  1. Authorized domains — Firebase Console → Authentication → Settings → Authorized domains → adicionar o domínio do deploy (ex.: excel.onpetro.xadm.biz). Sem isso, o signInWithPopup do Google falha no navegador.
  2. Provider Google — já habilitado no xadm-6ab81; nada a fazer.
  3. AUTH_SESSION_SECRET — segredo HS256 exclusivo deste deploy, ≥32 chars: openssl rand -hex 32. Nunca reusar de outro deploy/serviço.

Não é necessário o firebase-admin-sdk.json: a validação do ID token usa só o JWKS público do Google.

Passos

Configurar as variáveis no Coolify:

Variável Obrigatória Padrão Descrição
AUTH_FIREBASE_PROJECT_ID sim — xadm-6ab81
AUTH_FIREBASE_API_KEY sim — Web API key (valor público)
AUTH_FIREBASE_AUTH_DOMAIN sim — xadm-6ab81.firebaseapp.com
AUTH_FIREBASE_APP_ID sim — Web App ID (valor público)
AUTH_SESSION_SECRET sim — segredo HS256 ≥32 chars, exclusivo
AUTH_SESSION_TTL_SECONDS não 28800 (8 h) TTL do cookie
AUTH_COOKIE_SECURE não true Secure (true em prod HTTPS)
AUTH_XADM_EMAIL_DOMAIN não xadm.com.br domínio aceito
AUTH_ISSUER não bi-comercial-xls claim iss do cookie de sessão (lib xadm-seguranca, decisão 0018). Não mudar — o valor é validado na verificação; alterar invalida todas as sessões em voo

Os 4 AUTH_FIREBASE_* são públicos (vão no HTML da página de login, por design do Firebase Web SDK). AUTH_SESSION_SECRET é o único segredo — nunca logado, nunca exposto em HTML.

Fluxo de login / logout

  1. Usuário sem sessão abre uma view → o servidor redireciona para /login?from=<path>.
  2. /login mostra "Entrar com Google"; o clique abre o popup do Google.
  3. O navegador obtém o ID token do Firebase e faz POST /login/callback.
  4. O servidor valida CSRF + ID token + domínio @xadm.com.br, emite o cookie xadm_session e redireciona de volta para o from original.
  5. A navbar passa a mostrar o email logado + "Sair" (POST /logout, expira o cookie).

Verificação

  • Abrir uma view (/processamentos) → redireciona para /login → "Entrar com Google" → após login com conta @xadm.com.br, volta para a view com o email na navbar.
  • Conta fora do domínio → "Acesso restrito a emails @xadm.com.br" (esperado).

Reversão / comportamento sem as envs

Não há "desligar" explícito — o comportamento depende das envs e do ambiente:

Situação Comportamento
Envs AUTH_* completas filtro ativo (views exigem login)
Envs ausentes e ambiente dev/test bypass (views públicas, WARN no log)
Envs ausentes e produção fail-closed (503 em todas as views)

Em produção, sempre configure as 5 variáveis obrigatórias.

Sessão e segurança (caveats)

  • Sessão stateless (cookie xadm_session, JWT HS256 auto-contido): não há revogação server-side. O logout só expira o cookie no navegador; um token vazado vale até expirar. O TTL de 8 h (AUTH_SESSION_TTL_SECONDS) limita essa janela.
  • CSRF: os forms POST de view (/admin/nuke-replication, /processamentos/{id}/excluir, /processamentos/{id}/reprocessar, /processamentos/{id}/reprocessar-lote e /processamentos/reprocessar-erros) carregam _csrf derivado da sessão; ausente/divergente → 403. O enforcement só vale com auth ativo — em dev/test (bypass) o CSRF não é exigido.
  • Qualquer sessão válida reprocessa. Os três reprocessar* são ações de escrita liberadas para todo email @xadm.com.br logado — não há papel de operador vs. leitor. A trava é de estado, não de pessoa: o WHERE … AND status = 'ERRO' do resetarParaPendenteSeErro recusa (409) tudo que não esteja em ERRO, então o estrago possível é refazer um arquivo que já falhou. Mesmo critério do nuke em /admin.

Troubleshooting

Sintoma Causa / ação
Todas as views em 503 produção sem as 5 envs obrigatórias — configurar
Popup do Google falha (domínio) domínio do deploy não está em Authorized domains
Login OK mas volta sempre pro /login cookie não persistiu — checar AUTH_COOKIE_SECURE vs HTTPS
Acesso restrito a emails @xadm.com.br conta usada não é do domínio — usar conta @xadm.com.br
Bean falha no startup (secret curto) AUTH_SESSION_SECRET < 32 chars — gerar novo com openssl rand -hex 32
Login intermitente com erro do Google JWKS do Google indisponível → o servidor responde 503 + Retry-After; tentar de novo