docs: add zitadel and nextjs setup guidelines to replace legacy applications
This commit is contained in:
parent
c901580a49
commit
e42d616acd
1 changed files with 225 additions and 0 deletions
225
ZITADEL_SETUP.md
Normal file
225
ZITADEL_SETUP.md
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
# Zitadel + Next.js App Router Integration Setup
|
||||
|
||||
Guia corporativo atuando como Especialista em Engenharia de Software e DevOps para inicialização do ecossistema Zitadel on-premise (Baremetal/Binário direto) integrado à um ambiente moderno Next.js.
|
||||
|
||||
## Parte 1: Setup do Serviço de Autenticação (Zitadel)
|
||||
|
||||
### 1. Download e Instalação (Binário Oficial)
|
||||
O Zitadel é distribuído em um binário em Go altamente otimizado. Para ambientes baseados em Linux/MacOS:
|
||||
|
||||
```bash
|
||||
# Definir a versão alvo
|
||||
export ZITADEL_VERSION="v2.66.3" # ou a tag latest estável
|
||||
|
||||
# Download macOS (usar darwin_arm64 para Apple Silicon ou darwin_amd64 para Intel)
|
||||
# Download Linux (usar linux_amd64 ou linux_arm64)
|
||||
curl -sLO "https://github.com/zitadel/zitadel/releases/download/${ZITADEL_VERSION}/zitadel_Linux_x86_64.tar.gz"
|
||||
|
||||
# Extrair
|
||||
tar -xvf zitadel_Linux_x86_64.tar.gz
|
||||
|
||||
# Mover binário pro path
|
||||
sudo mv zitadel /usr/local/bin/
|
||||
```
|
||||
|
||||
### 2. Configuração Básica e Local (Sem TLS / Insecure)
|
||||
Crie um arquivo `config.yaml` voltado para acoplamento interno. Ele especifica conexões sem segredos e expõe a interface sem demandar certificados TLS para localhost.
|
||||
|
||||
**`config.yaml`**:
|
||||
```yaml
|
||||
ExternalSecure: false
|
||||
Port: 8080
|
||||
|
||||
# Conexão com sua base PostgreSQL limpa inicializada (Pode ser local/Docker)
|
||||
Database:
|
||||
postgres:
|
||||
Host: localhost
|
||||
Port: 5432
|
||||
Database: zitadel
|
||||
User:
|
||||
Username: "postgres"
|
||||
Password: "your-password"
|
||||
SSL:
|
||||
Mode: disable
|
||||
Admin:
|
||||
Username: "postgres"
|
||||
Password: "your-password"
|
||||
SSL:
|
||||
Mode: disable
|
||||
```
|
||||
|
||||
### 3. Setup e Start
|
||||
A injeção dos esquemas base e a inicialização do container de autenticação:
|
||||
|
||||
```bash
|
||||
# 1. Aplicar migrações ao PostgreSQL provisionado
|
||||
zitadel setup --masterkey "a-32-byte-master-key-must-be-set" --config config.yaml
|
||||
|
||||
# 2. Levantar o Listener HTTP
|
||||
zitadel start --masterkey "a-32-byte-master-key-must-be-set" --config config.yaml
|
||||
```
|
||||
|
||||
*O setup inicial gerará um log contendo as informações do usuário `machine` primário (`zitadel-admin`). Guarde este log/json.*
|
||||
|
||||
### 4. Gerar chaves (Service User \/ Machine Key)
|
||||
1. Acesse `http://localhost:8080/ui/console`.
|
||||
2. Vá em **Projects** > (Seu projeto) > **Service Users**.
|
||||
3. Crie um novo. Confirme.
|
||||
4. Na página de gerenciar esse Service User, vá em **Keys** e adicione uma nova.
|
||||
5. Selecione formato **JSON**. Ele fará o download da `machinekey.json`. Guarde esse documento num `secrets/` do Next.
|
||||
|
||||
---
|
||||
|
||||
## Parte 2: Dashboard Next.js (App Router + Tailwind)
|
||||
|
||||
### 1. Inicializando Projetos
|
||||
```bash
|
||||
npx create-next-app@latest admin-dashboard --typescript --tailwind --eslint --app
|
||||
cd admin-dashboard
|
||||
npm install @zitadel/nextjs @zitadel/server
|
||||
```
|
||||
|
||||
### 2. Middleware de Proteção
|
||||
Crie um arquivo em `src/middleware.ts` para capturar a sessão sem bloqueios pesados.
|
||||
|
||||
```typescript
|
||||
import { NextResponse } from "next/server";
|
||||
import type { NextRequest } from "next/server";
|
||||
|
||||
export function middleware(request: NextRequest) {
|
||||
// A SDK usa os tokens armazenados em cookies.
|
||||
const hasZitadelCookie = request.cookies.some((c) => c.name.includes("zitadel"));
|
||||
|
||||
if (!hasZitadelCookie && request.nextUrl.pathname.startsWith("/dashboard")) {
|
||||
return NextResponse.redirect(new URL("/api/auth/signin", request.url));
|
||||
}
|
||||
|
||||
return NextResponse.next();
|
||||
}
|
||||
|
||||
export const config = {
|
||||
matcher: ["/dashboard/:path*"],
|
||||
};
|
||||
```
|
||||
|
||||
### 3. Server Component de Dashboard
|
||||
Interface estilizada de alto nível para exibição do IAM e profile contextual, injetante de tailwind corporativo de forma nativa e sem `use client`.
|
||||
|
||||
`src/app/dashboard/page.tsx`
|
||||
```tsx
|
||||
import { getSession } from '@zitadel/nextjs';
|
||||
// A API Wrapper SDK para o client Admin gRPC/REST do Zitadel
|
||||
import { createZitadelClient } from '@zitadel/server';
|
||||
import fs from 'fs/promises';
|
||||
|
||||
export default async function DashboardPage() {
|
||||
const session = await getSession();
|
||||
|
||||
if (!session?.user) {
|
||||
return <p className="text-zinc-400 font-mono">Não autorizado.</p>;
|
||||
}
|
||||
|
||||
// 1. Instanciando Client IAM via Machine JSON
|
||||
const keyFile = await fs.readFile(process.cwd() + '/secrets/machinekey.json', 'utf8');
|
||||
const zitadelClient = createZitadelClient({
|
||||
token: keyFile,
|
||||
apiUrl: process.env.ZITADEL_API_URL!,
|
||||
});
|
||||
|
||||
// 2. Coletando Orgs
|
||||
let organizations: any[] = [];
|
||||
try {
|
||||
const { orgs } = await zitadelClient.management.listOrgs({});
|
||||
organizations = orgs || [];
|
||||
} catch (error) {
|
||||
console.error("Falha ao buscar organizações", error);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-zinc-950 text-zinc-100 flex flex-col p-8 font-sans">
|
||||
<div className="max-w-5xl w-full mx-auto space-y-6">
|
||||
|
||||
<header className="border-b border-zinc-800 pb-4 mb-8">
|
||||
<h1 className="text-3xl font-bold tracking-tight">Identity Control Plane</h1>
|
||||
<p className="text-zinc-500 mt-2">Visão Administrativa Zitadel</p>
|
||||
</header>
|
||||
|
||||
<section className="bg-zinc-900 rounded-xl border border-zinc-800 p-6 shadow-2xl">
|
||||
<h2 className="text-xl font-semibold mb-4 text-white">Perfil Atual</h2>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="bg-black/50 p-4 rounded-lg">
|
||||
<span className="text-xs text-zinc-500 uppercase">Usuário</span>
|
||||
<p className="font-medium font-mono text-zinc-300 mt-1">{session.user.name}</p>
|
||||
</div>
|
||||
<div className="bg-black/50 p-4 rounded-lg">
|
||||
<span className="text-xs text-zinc-500 uppercase">E-mail ID</span>
|
||||
<p className="font-medium font-mono text-blue-400 mt-1">{session.user.email}</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="bg-zinc-900 rounded-xl border border-zinc-800 p-6 shadow-2xl">
|
||||
<h2 className="text-xl font-semibold mb-4 flex items-center justify-between">
|
||||
<span>Organizações <span className="ml-2 text-xs bg-indigo-500/20 text-indigo-400 px-2 py-1 rounded-md">Service API</span></span>
|
||||
</h2>
|
||||
|
||||
<ul className="space-y-3">
|
||||
{organizations.length === 0 ? (
|
||||
<li className="text-zinc-500 text-sm">Nenhuma organização encontrada sob este tenant.</li>
|
||||
) : (
|
||||
organizations.map((org) => (
|
||||
<li key={org.id} className="flex justify-between items-center p-4 bg-black/40 rounded-lg border border-zinc-800 hover:border-indigo-500 transition-colors cursor-pointer">
|
||||
<div className="flex flex-col">
|
||||
<span className="font-medium text-zinc-200">{org.name}</span>
|
||||
<span className="text-xs font-mono text-zinc-600 mt-1">ID: {org.id}</span>
|
||||
</div>
|
||||
<span className="text-xs px-3 py-1 bg-emerald-500/10 text-emerald-400 rounded-full border border-emerald-500/20">Active</span>
|
||||
</li>
|
||||
))
|
||||
)}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Parte 3: Guia de Integração Ambiente Local
|
||||
|
||||
### 1. Preparação Local Next.js (`.env.local`)
|
||||
Adicione o endpoint do provedor OIDC e credenciais do dashboard para sua integração funcionar na rota cliente:
|
||||
|
||||
```env
|
||||
# SDK NextAuth
|
||||
NEXTAUTH_URL="http://localhost:3000"
|
||||
NEXTAUTH_SECRET="uma-string-secreta-gigante-aqui-random"
|
||||
|
||||
# Zitadel Configuration (A porta que você mapeou no config.yaml)
|
||||
ZITADEL_ISSUER="http://localhost:8080"
|
||||
ZITADEL_CLIENT_ID="AQUI_VAI_O_CLIENT_ID_DO_SEU_WEB_APP"
|
||||
ZITADEL_CLIENT_SECRET="AQUI_VAI_O_SECRET_DO_WEB_APP"
|
||||
|
||||
# API Endpoint (Utilizado pelo Client JWT Server para as Orgs)
|
||||
ZITADEL_API_URL="http://localhost:8080"
|
||||
```
|
||||
|
||||
### 2. Rodando o Ecossistema Completamente Local
|
||||
|
||||
Para rodar os serviços paralelos no seu ambiente de terminal:
|
||||
|
||||
**No Terminal 1 (O IAM Authority Zitadel):**
|
||||
```bash
|
||||
./zitadel start --masterkey "a-32-byte-master-key-must-be-set" --config config.yaml
|
||||
```
|
||||
|
||||
**No Terminal 2 (O Dashboard Edge-side):**
|
||||
```bash
|
||||
cd admin-dashboard
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Essa arquitetura garante que a requisição de contexto do OIDC caia por trás dos painéis locais e que você utilize a `machinekey` (Service Account) internamente em rotas NodeJS sem jamais vazar a chave sensível da infraestrutura, além do Tailwind em Dark Mode proporcionar uma visualização profissional para auditoria de redes.
|
||||
Loading…
Reference in a new issue