> ## Documentation Index
> Fetch the complete documentation index at: https://docs.easygoal.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Autenticação Cross-Domain

> Como integrar apps externos ao SSO EasyGoal via eg_session e eg_token.

## Visão Geral

O SSO distribui autenticação para apps em outros domínios de duas formas:

| Cenário                                                | Mecanismo                                 | Quando usar                        |
| ------------------------------------------------------ | ----------------------------------------- | ---------------------------------- |
| **App interno** (subdomínio `.easygoal.com.br`)        | `?eg_session=<token>` no redirect         | app-front, club LP, sites internos |
| **App externo** (domínio externo, API key obrigatória) | `?eg_token=<token>` + `POST /auth/verify` | parceiros, integrações terceiras   |

O browser envia o cookie `eg_session` (setado em `.easygoal.com.br`) naturalmente para todos os subdomínios — o SSO apenas replica o token para apps que não alcançam o cookie.

***

## App Interno — Fluxo com `eg_session`

```
[App] → SSO /auth/login?redirect_to=https://app.easygoal.com.br/auth/callback
    ↓
SSO autentica → seta cookie eg_session em .easygoal.com.br
    ↓
SSO /auth/welcome → redirect para https://app.easygoal.com.br/auth/callback?eg_session=<token>
    ↓
App /auth/callback: handleAuthCallback → salva eg_session no cookie local → redirect
```

**Setup mínimo:**

```ts theme={null}
// src/app/auth/callback/route.ts
import { createCallbackRoute } from '@easygoal/packages/auth/server';

export const GET = createCallbackRoute({
  ssoUrl: process.env.NEXT_PUBLIC_SSO_URL,
  appUrl: process.env.NEXT_PUBLIC_APP_URL,
});
```

```tsx theme={null}
// layout.tsx
import { EgSessionProvider } from '@easygoal/packages/auth/client';

export default function RootLayout({ children }) {
  return <EgSessionProvider>{children}</EgSessionProvider>;
}
```

O `EgSessionProvider` lê `/api/auth/session` (rota gerada pelo package) que retorna os claims do `eg_session` cookie.

***

## App Externo — Fluxo com `eg_token`

Para apps em domínios externos (sem acesso ao cookie `.easygoal.com.br`):

```
[App Externo] → SSO /auth/login?redirect_to=<callback>&api_key=<chave>
    ↓
SSO autentica → redirect_to?eg_token=<token_temporário_5min>
    ↓
App /auth/callback (server-side):
  POST /auth/verify (Authorization: Bearer <api_key>, body: { token: eg_token })
  → retorna eg_session JWT
  → salva eg_session no cookie local
    ↓
Redirect para destino final
```

**Setup:**

```ts theme={null}
// src/app/auth/callback/route.ts
import { createCallbackRoute } from '@easygoal/packages/auth/server';

export const GET = createCallbackRoute({
  ssoUrl: process.env.NEXT_PUBLIC_SSO_URL,
  appUrl: process.env.NEXT_PUBLIC_APP_URL,
  apiKey: process.env.EG_API_KEY, // obrigatório para apps externos
});
```

```env theme={null}
NEXT_PUBLIC_SSO_URL=https://sso.easygoal.com.br
NEXT_PUBLIC_APP_URL=https://meuapp.com
EG_API_KEY=eg_live_sua_chave_aqui
```

<Warning>
  `EG_API_KEY` é usada server-side em `POST /auth/verify`. Nunca exponha como `NEXT_PUBLIC_`. Para apps que precisam iniciar o login via client, use apenas a URL pública do SSO — o `api_key` só é necessário no callback server-side.
</Warning>

### Pré-requisitos para apps externos

1. Produto registrado no SSO com `status: approved`
2. URL do callback cadastrada em `saas_products.redirect_urls`
3. API key ativa para o produto

***

## Verificar sessão server-side

Para proteger rotas ou verificar autenticação em Server Components/middleware:

```ts theme={null}
// Opção A: via GET /auth/check (lê cookie eg_session da requisição)
const res = await fetch(`${SSO_URL}/auth/check`, {
  headers: { cookie: request.headers.get('cookie') ?? '' },
  cache: 'no-store',
});
const { authenticated, session } = await res.json();

// Opção B: via EgSessionProvider (client-side)
const { user, isReady } = useEgSession();
```

O `/auth/check` é ideal para **middleware de proteção de rotas** — não redireciona, apenas retorna JSON com `{ authenticated, session }`.

***

## Proteção de páginas admin via `auth/check`

<Note>
  **Funcionalidade planejada.** Para proteger páginas da documentação (ou qualquer app) exclusivamente para administradores, seria necessário adicionar `is_super_admin` ao `EgSessionClaims` no SSO. O campo existe em `AuthUser` do monorepo mas ainda não é injetado no `eg_session` JWT. Após essa adição, o middleware pode verificar `session.is_super_admin === true` via `/auth/check`.
</Note>

Fluxo planejado:

```ts theme={null}
// middleware.ts
const { authenticated, session } = await checkSession(request);

if (pathname.startsWith('/admin')) {
  if (!authenticated || !session?.is_super_admin) {
    return NextResponse.redirect('/');
  }
}
```

***

## Checklist de Integração

<Check>Produto registrado no SSO (apenas para apps externos)</Check>
<Check>URL do callback cadastrada em `saas_products.redirect_urls`</Check>
<Check>Callback route implementado com `createCallbackRoute`</Check>
<Check>`EgSessionProvider` adicionado ao layout raiz</Check>
<Check>URL do callback cadastrada em **Supabase → Auth → Redirect URLs**</Check>
<Check>Variáveis `NEXT_PUBLIC_SUPABASE_URL`, `NEXT_PUBLIC_SUPABASE_ANON_KEY`, `NEXT_PUBLIC_SSO_URL` configuradas</Check>
