Pular para o conteúdo principal

Autenticação Segura em Apps via Iframe

Bem-vindo ao guia de desenvolvimento de aplicativos integrados!

Para garantir a segurança dos dados do nosso Parceiro (Restaurante) e a fluidez da operação no Geraldo, a sua aplicação será embutida em nossa plataforma através de um Iframe. Como Iframes operam em contextos de terceiros (cross-site), a gestão de sessão deve seguir padrões rigorosos de segurança e usabilidade.

Abaixo, detalhamos o padrão arquitetural exigido: OAuth2 (Authorization Code) com Popup e gestão de sessão via Cookies Seguros.

🔐 1. O Fluxo de Autenticação (OAuth2 com Popup)

Para evitar bloqueios de segurança dos navegadores e garantir uma transição suave, o login não deve ocorrer dentro do Iframe. O padrão exigido é o Authorization Code Flow, com a troca de tokens realizada exclusivamente pelo seu Backend.

REGRA DE OURO — A Redirect URI é Fixa e Inalterável:
Em todo o seu fluxo de autorização e troca de tokens, a ÚNICA redirect_uri válida e aceita pelo nosso sistema é:

👉 https://geraldo-restaurantes.aiqfome.com/apps-e-integracoes/auth/callback


Diagrama de Sequência
sequenceDiagram
participant User as Restaurante
participant Opener as App no Iframe
participant Popup as Popup de Login
participant IdP as Identity provider
participant Callback as Rota Callback Geraldo
participant API as Seu Backend

User->>Opener: Inicia login
Opener->>Popup: Abre URL de autorização
User->>Popup: Autentica e autoriza
Popup->>IdP: Redireciona com code
IdP->>Callback: GET redirect_uri?code=...
Callback->>Opener: postMessage({ type, code })
Opener->>API: POST { code }
API->>IdP: POST /token (secret + code)
IdP-->>API: access_token (+ refresh)
API-->>Opener: Sucesso (Response com Set-Cookie)
Opener->>Opener: Renderiza App (Sessão Ativa)

🛠️ 2. Implementação Passo a Passo

Passo 1 — Abrir o Popup de Autorização (Front-end do Integrador)

O seu aplicativo (no Iframe) abre a URL do Provedor de Identidade (IdP) em uma nova janela.

function openLoginPopup() {
const params = new URLSearchParams({
client_id: CLIENT_ID,
// A URL DEVE SER EXATAMENTE ESTA:
redirect_uri: "https://geraldo-restaurantes.aiqfome.com/apps-e-integracoes/auth/callback",
response_type: "code",
scope: SCOPES,
});

const authUrl = `${IDP_AUTHORIZE_BASE_URL}/oauth/authorize?${params}`;
window.open(authUrl, "oauthPopup", "width=600,height=600");
}

Passo 2 — Escutar o Código e Acionar o Backend (Front-end do Integrador)

Seu aplicativo no Iframe deve ficar escutando a janela pai para capturar o código.

useEffect(() => {
async function handleMessage(event) {
const data = event.data;
if (!data || data.type !== "authCode" || data.code == null) {
return;
}

// Envia o código para o SEU backend realizar a troca
const res = await fetch("/api/oauth/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ code: data.code }),
});

if (res.ok) {
window.location.reload(); // Ou atualiza o estado para renderizar a dashboard
}
}

window.addEventListener("message", handleMessage);
return () => window.removeEventListener("message", handleMessage);
}, []);

Passo 3 — Troca de Token e Gestão de Sessão (Seu Backend)

Este é o ponto mais crítico para a segurança. O seu backend recebe o código, troca pelo token no IdP e cria a sessão do usuário utilizando Cookies.

Por que Cookies?

O armazenamento de tokens em localStorage é estritamente desencorajado devido a riscos de XSS. A única forma segura e funcional em contextos de Iframe é o uso de cookies.

Configuração Obrigatória do Cookie:

Para funcionar dentro do Iframe, o cookie DEVE conter:

  • HttpOnly: Impede acesso via JavaScript.
  • Secure: Exige conexão HTTPS.
  • SameSite=None: Permite o envio do cookie no contexto cross-site do Iframe.
// Exemplo no seu Backend ao pedir o token ao IdP
const body = new URLSearchParams({
grant_type: "authorization_code",
code: authorizationCode,
client_id: process.env.OAUTH_CLIENT_ID,
client_secret: process.env.OAUTH_CLIENT_SECRET, // Mantido apenas no servidor
// DEVE SER EXATAMENTE A MESMA DO PASSO 1:
redirect_uri: "https://geraldo-restaurantes.aiqfome.com/apps-e-integracoes/auth/callback",
});

// ... fetch para o token endpoint ...

// Salvando o token via Cookie na resposta para o Front-end
res.cookie('session_token', token, {
httpOnly: true,
secure: true,
sameSite: 'none'
});
res.status(200).send({ message: "Sessão iniciada" });

🔄 3. Sincronização em Tempo Real (WebSockets)

Para evitar que o usuário do restaurante precise recarregar o Iframe (o que reinicia o ciclo de renderização), a sua aplicação deve ser reativa.

  • Atualização Silenciosa: Utilize WebSockets ou SSE para ouvir eventos do seu backend (ex: entrada ou alteração de status de pedidos).
  • Experiência Fluida: Atualize a interface dinamicamente sem necessidade de usar F5. Telas estáticas geram atrito operacional e chamados de suporte.

✅ 4. Checklist Final de Homologação

ItemRequisito Obrigatório
redirect_uriUsar EXATAMENTE https://geraldo-restaurantes.aiqfome.com/apps-e-integracoes/auth/callback na autorização e na troca de token.
Armazenamento de TokenProibido o uso de localStorage. Deve ser feito exclusivamente via Cookie Seguro (Set-Cookie via Backend).
Atributos do CookiePresença obrigatória das flags HttpOnly, Secure e SameSite=None.
client_secretDeve permanecer protegido e ser utilizado apenas no ambiente do seu servidor.
UX ReativaA tela deve atualizar dados automaticamente (Websocket/SSE) sem refresh manual.

aiqfome

© Copyright 2007-2026 aiqfome LTDA .