Communitygithub.com

agents-inc/skills

Autenticação gerenciada pelo Clerk - ClerkProvider, middleware, componentes pré-construídos, hooks, autenticação no servidor, organizações e webhooks

O que é skills?

Este skill fornece padrões e práticas recomendadas para implementar autenticação gerenciada pelo Clerk em aplicações Next.js. Ele cobre todo o ciclo de vida da autenticação: configuração do ClerkProvider e middleware, uso de componentes de UI pré-construídos como `<SignIn>`, `<SignUp>` e `<UserButton>`, e a substituição dos componentes obsoletos `<SignedIn>`/`<SignedOut>` pelo novo `<Show>` do Core 3. No lado do servidor, ensina como usar `auth()` e `currentUser()` do `@clerk/nextjs/server` para proteger rotas, actions do servidor e rotas de API, com ênfase em defesa em profundidade (proteção no middleware E na camada de dados). O skill também aborda autenticação no cliente com hooks como `useUser`, `useAuth` e `useOrganization`, gerenciamento de organizações com RBAC (controle de acesso baseado em papéis e permissões), e o tratamento seguro de webhooks com verificação de assinatura via `verifyWebhook`. Inclui frameworks de decisão para escolher entre autenticação no cliente vs. servidor, estratégias de proteção de rotas e seleção de componentes, além de alertas sobre erros comuns e práticas inseguras.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/agents-inc/skills/tree/HEAD/src/skills/api-auth-clerk

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Padrões de Autenticação Clerk

Guia Rápido: O Clerk fornece autenticação gerenciada com componentes de UI pré-construídos, helpers do lado do servidor e multi-tenancy baseado em organizações. Use clerkMiddleware() para proteção de rotas, <Show> para renderização condicional, hooks para estado no cliente e auth()/currentUser() para autenticação no servidor. Clerk Core 3 (2026) substitui <SignedIn>/<SignedOut> por <Show>, renomeia o arquivo de middleware para proxy.ts (Next.js 16+) e consolida pacotes.


<critical_requirements>

CRÍTICO: Antes de Usar Este Skill

Todo código deve seguir as convenções do projeto no CLAUDE.md (kebab-case, exportações nomeadas, ordenação de imports, import type, constantes nomeadas)

(Você DEVE usar @clerk/nextjs/server para TODOS os imports do lado do servidor – NUNCA importe helpers de servidor de @clerk/nextjs)

(Você DEVE verificar webhooks usando o helper verifyWebhook do Clerk – NUNCA confie em payloads de webhook não verificados)

(Você DEVE usar o componente <Show> em vez dos obsoletos <SignedIn>/<SignedOut>/<Protect> – eles foram removidos no Core 3)

(Você NÃO DEVE passar o objeto completo currentUser() para o cliente – ele contém privateMetadata que deve permanecer no servidor)

(Você DEVE proteger as rotas TANTO no middleware QUANTO na camada de acesso a dados – apenas o middleware é insuficiente)

</critical_requirements>


Detecção automática: Clerk, ClerkProvider, clerkMiddleware, @clerk/nextjs, useUser, useAuth, useClerk, useSession, useOrganization, SignIn, SignUp, UserButton, UserProfile, OrganizationSwitcher, auth(), currentUser(), CLERK_SECRET_KEY, NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, Show when="signed-in"

Quando usar:

  • Adicionar autenticação e gerenciamento de usuários a uma aplicação
  • Construir aplicativos B2B multi-tenant com controle de acesso baseado em organizações
  • Usar componentes de UI de login/cadastro pré-construídos com temas personalizáveis
  • Proteger rotas com middleware e verificações de autorização no servidor
  • Sincronizar dados de usuário do Clerk com seu banco de dados via webhooks

Padrões principais abordados:

  • Configuração do ClerkProvider, variáveis de ambiente, configuração de middleware
  • Componentes de UI pré-construídos (<SignIn>, <SignUp>, <UserButton>, <Show>)
  • Hooks do lado do cliente (useUser, useAuth, useSession, useOrganization)
  • Autenticação no servidor (auth(), currentUser()) em Componentes Servidor, Manipuladores de Rota, Ações do Servidor
  • Proteção de rotas com middleware usando clerkMiddleware() e createRouteMatcher()
  • Multi-tenancy baseado em organizações com papéis e permissões
  • Manipulação de webhooks com verificação de assinatura Svix

Quando NÃO usar:

  • Exigência de autenticação auto-hospedada (controle total sobre armazenamento de dados de autenticação)
  • Não é possível usar um serviço de autenticação de terceiros (restrições de conformidade/regulamentação)
  • Autenticação simples por chave de API (middleware personalizado é suficiente)
  • Restrições orçamentárias impedem o uso de um serviço gerenciado

Recursos Detalhados:

  • reference.md - Estruturas de decisão, referência rápida de hooks, guia de migração para Core 3
  • examples/core.md - ClerkProvider, variáveis de ambiente, configuração de middleware
  • examples/components.md - Componentes pré-construídos, personalização, propriedade appearance
  • examples/hooks.md - useUser, useAuth, useSession, estados de carregamento, renderização condicional
  • examples/server.md - Componentes Servidor, rotas de API, Ações do Servidor, manipulação de webhooks
  • examples/organizations.md - Gerenciamento de organizações, papéis, permissões, RBAC

Filosofia

Clerk é uma plataforma de autenticação gerenciada que lida com todo o ciclo de vida da autenticação: cadastro, login, gerenciamento de sessão, perfis de usuário, organizações e MFA. Em vez de construir autenticação do zero, você integra o SDK e os componentes pré-construídos do Clerk.

Princípios fundamentais:

  1. Defesa em profundidade – Proteja as rotas na camada de middleware E verifique a autenticação em cada ponto de acesso a dados. Apenas o middleware é insuficiente (CVE-2025-29927 demonstrou vulnerabilidades de bypass de middleware).
  2. Autenticação primeiro no servidor – Use auth() e currentUser() em Componentes Servidor e Manipuladores de Rota. Use hooks do cliente (useUser, useAuth) apenas quando precisar de estado reativo no cliente.
  3. Pré-construído sobre personalizado – Use os componentes <SignIn>, <SignUp>, <UserButton> do Clerk. Construa fluxos personalizados apenas quando os componentes pré-construídos realmente não puderem atender aos requisitos.
  4. Organizações para multi-tenancy – Use Organizações do Clerk com papéis e permissões para aplicativos B2B. Não construa sistemas de tenant personalizados sobre o modelo de usuário do Clerk.
  5. Sincronização orientada por webhooks – Sincronize dados do Clerk com seu banco de dados via webhooks, não por polling. Sempre verifique as assinaturas dos webhooks com verifyWebhook.

Quando usar Clerk:

  • Você precisa de autenticação rapidamente com o mínimo de código personalizado
  • Você deseja componentes de UI pré-construídos para login/cadastro/gerenciamento de usuário
  • Você precisa de multi-tenancy baseado em organizações com RBAC
  • Você deseja MFA gerenciado, SSO (SAML/OIDC) e login social

Quando NÃO usar Clerk:

  • Você precisa de controle total sobre o armazenamento de dados de autenticação (exigência auto-hospedada)
  • Você não pode usar um serviço de autenticação de terceiros (conformidade/regulamentação)
  • Seu aplicativo precisa apenas de autenticação simples por chave de API
  • Restrições orçamentárias impedem o uso de um serviço gerenciado

Padrões Principais

Padrão 1: Configuração do ClerkProvider e Middleware

Todo aplicativo Clerk precisa de <ClerkProvider> envolvendo o app e clerkMiddleware() protegendo as rotas. Veja examples/core.md para exemplos completos de configuração.

Regras principais:

  • ClerkProvider vai dentro de <body>, não envolvendo <html> – Core 3 exige isso
  • Use a variável de ambiente NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, nunca codifique chaves
  • O arquivo de middleware é proxy.ts no Next.js 16+ ou middleware.ts no Next.js <=15
  • O endpoint de webhook deve estar na lista de rotas públicas (verificado separadamente por verifyWebhook)
  • CLERK_WEBHOOK_SIGNING_SECRET é a variável de ambiente para assinatura de webhook (não CLERK_WEBHOOK_SECRET)
// proxy.ts (Next.js 16+) ou middleware.ts (Next.js <=15)
const isPublicRoute = createRouteMatcher([
  "/",
  "/sign-in(.*)",
  "/sign-up(.*)",
  "/api/webhooks(.*)",
]);

export default clerkMiddleware(async (auth, req) => {
  if (!isPublicRoute(req)) {
    await auth.protect();
  }
});

Por que é bom: Rotas públicas explicitamente na lista de permissões, todo o resto requer autenticação, endpoint de webhook é público (verificado separadamente)

// RUIM: clerkMiddleware() sem callback
export default clerkMiddleware(); // TODAS as rotas são PÚBLICAS por padrão!

Por que é ruim: clerkMiddleware() sem callback anexa dados de autenticação mas não protege nenhuma rota


Padrão 2: Componentes de UI Pré-construídos e <Show>

Use <Show> para renderização condicional (substituto do Core 3 para <SignedIn>/<SignedOut>/<Protect>). Veja examples/components.md para exemplos completos.

<Show when="signed-out"><SignInButton /></Show>
<Show when="signed-in"><UserButton /></Show>
<Show when={{ role: "org:admin" }}><AdminPanel /></Show>
<Show when={(has) => has({ permission: "org:invoices:manage" })}><InvoiceManager /></Show>

Por que é bom: <Show> é a API do Core 3, suporta condições string/objeto/callback, prop fallback para não autorizado

// RUIM: Obsoleto – removido no Core 3
<SignedIn>...</SignedIn>
<SignedOut>...</SignedOut>
<Protect role="admin">...</Protect>

Por que é ruim: <SignedIn>, <SignedOut>, <Protect> removidos no Core 3, use <Show> com a prop when

Páginas de login/cadastro exigem segmentos de rota catch-all [[...sign-in]] para fluxos de várias etapas (MFA, callbacks OAuth).


Padrão 3: Hooks do Lado do Cliente

Use hooks em Componentes Cliente para estado de autenticação reativo. Sempre verifique isLoaded antes de acessar os dados. Veja examples/hooks.md para exemplos completos.

"use client";
const { isLoaded, isSignedIn, user } = useUser();
if (!isLoaded) return <div>Carregando...</div>;
if (!isSignedIn) return <div>Por favor, faça login</div>;
// Agora é seguro acessar user.firstName, user.emailAddresses, etc.

Por que é bom: Previne erros de hidratação ao acessar undefined durante a inicialização, previne TypeError ao acessar null quando desconectado

// RUIM: Acessando user sem guardas
const { user } = useUser();
return <p>{user.firstName}</p>; // Erro em tempo de execução quando isLoaded=false ou isSignedIn=false

Por que é ruim: user é undefined até carregar e null quando desconectado

Hooks principais:

  • useUser() – dados do perfil do usuário (nome, email, avatar)
  • useAuth() – tokens de sessão (getToken()), userId, orgId, has() para autorização
  • useOrganization() – dados da organização ativa, associação, lista paginada de membros
  • useReverification() – re-autenticar antes de ações sensíveis (Core 3)

No Core 3, getToken() lança ClerkOfflineError quando offline em vez de retornar null – sempre envolva em try/catch.


Padrão 4: Autenticação no Lado do Servidor

Use auth() e currentUser() de @clerk/nextjs/server. Veja examples/server.md para exemplos completos.

auth() – leve, sem chamada de API, lê claims da sessão:

import { auth } from "@clerk/nextjs/server";
const { userId, orgId, isAuthenticated, redirectToSignIn } = await auth();
if (!isAuthenticated) return redirectToSignIn();

currentUser() – objeto de usuário completo, faz chamada à API Backend:

import { currentUser } from "@clerk/nextjs/server";
const user = await currentUser();
// CRÍTICO: Selecione campos seguros antes de passar para componentes cliente
const safeData = { firstName: user.firstName, imageUrl: user.imageUrl };

Por que é crítico: currentUser() retorna privateMetadata que nunca deve chegar ao cliente. Selecione campos explicitamente.

Defesa em profundidade: A autenticação DEVE ser verificada em cada Ação do Servidor e Manipulador de Rota, não apenas no middleware:

"use server";
const { userId } = await auth();
if (!userId) throw new Error("Não autorizado");
// userId escopo de todas as consultas/mutações para o usuário atual

Padrão 5: Autorização com Papéis e Permissões

Use auth.protect() ou has() para controle de acesso granular. Veja examples/organizations.md para padrões RBAC.

// Middleware: proteção de rota baseada em papel
await auth.protect((has) => has({ role: "org:admin" }));

// Componente Servidor: verificação de permissão
const { has } = await auth();
if (!has({ permission: "org:invoices:delete" })) redirect("/dashboard");

// Cliente: renderização condicional por papel
<Show when={{ role: "org:admin" }}><AdminPanel /></Show>

Formato de permissão: org:<feature>:<action> (ex.: org:invoices:create, org:reports:read)

Papéis padrão: org:admin (todas as permissões), org:member (somente leitura). Papéis personalizados configurados no Painel do Clerk.


Padrão 6: Manipulação de Webhooks

Use webhooks do Clerk (via Svix) para sincronizar dados de usuário com seu banco de dados. Veja examples/server.md para o manipulador completo.

import { verifyWebhook } from "@clerk/nextjs/webhooks";

export async function POST(req: Request) {
  const evt = await verifyWebhook(req); // lê a variável de ambiente CLERK_WEBHOOK_SIGNING_SECRET
  // evt.type: "user.created" | "user.updated" | "user.deleted" | "organization.*" | ...
  // evt.data: UserJSON | OrganizationJSON | etc.
}

Por que é bom: verifyWebhook valida a assinatura Svix, sempre retorna 200 para evitar novas tentativas, a rota de webhook é pública no middleware (verificada pela assinatura, não pela autenticação)

// RUIM: Sem verificação de assinatura
const body = await req.json(); // Qualquer um pode POSTAR dados falsos!
await db.insert(users).values(body.data); // Vulnerabilidade de segurança

Por que é ruim: Nenhuma verificação de assinatura significa que qualquer um pode enviar eventos de webhook falsos para seu endpoint

Importe tipos de @clerk/shared/types (Core 3): UserJSON, OrganizationJSON, OrganizationMembershipJSON


<decision_framework>

Estrutura de Decisão

Autenticação Cliente vs Servidor

Onde você precisa de dados de autenticação?
|-- Componente Servidor, Manipulador de Rota, Ação do Servidor
|   |-- Precisa apenas de userId/sessionId? --> auth()
|   |-- Precisa do objeto de usuário completo? --> currentUser()
|   |-- Precisa proteger a rota? --> auth.protect()
|   +-- Precisa de contexto de organização? --> auth() retorna orgId, orgRole
|
+-- Componente Cliente (UI interativa)
    |-- Precisa de dados do perfil do usuário? --> useUser()
    |-- Precisa de dados de sessão/token? --> useAuth()
    |-- Precisa de dados da organização? --> useOrganization()
    +-- Precisa da API Clerk de baixo nível? --> useClerk()

Estratégia de Proteção de Rotas

Que tipo de rota é?
|-- Pública (landing, login, cadastro, webhooks)
|   +-- Adicione ao matcher isPublicRoute, pule auth.protect()
|
|-- Autenticada (painel, perfil, configurações)
|   +-- auth.protect() no middleware + verificação auth() na camada de dados
|
+-- Autorizada (admin, específica de organização, com portão de permissão)
    |-- Baseada em papel? --> auth.protect({ role: "org:admin" })
    +-- Baseada em permissão? --> auth.protect((has) => has({ permission: "org:feature:action" }))

Escolha de Componente

De qual UI de autenticação você precisa?
|-- Página de login completa --> <SignIn /> em rota catch-all
|-- Página de cadastro completa --> <SignUp /> em rota catch-all
|-- Botão de login (modal) --> <SignInButton />
|-- Avatar do usuário + menu --> <UserButton />
|-- Editor de perfil completo --> <UserProfile />
|-- Alternador de organização --> <OrganizationSwitcher />
+-- Conteúdo condicional --> <Show when="signed-in"> ou <Show when={{ role: "..." }}>

</decision_framework>


<red_flags>

SINALIZADORES VERMELHOS

Problemas de Alta Prioridade:

  • Importar helpers de servidor de @clerk/nextjs em vez de @clerk/nextjs/server (quebra em Componentes Servidor)
  • Usar componentes obsoletos <SignedIn>/<SignedOut>/<Protect> (removidos no Core 3)
  • Passar o objeto completo currentUser() para componentes cliente (vaza privateMetadata)
  • Confiar em payloads de webhook sem verificação de assinatura verifyWebhook
  • Depender apenas do middleware para proteção de rotas (middleware pode ser contornado)
  • Importar tipos de @clerk/types em vez de @clerk/shared/types (mudança no Core 3)
  • Usar formatação camelCase para nomes de arquivos/constantes quando o projeto usa kebab-case

Problemas de Média Prioridade:

  • Ignorar o estado isLoaded em hooks do cliente (causa erros de tempo de execução)
  • Não tratar offline em getToken() (Core 3 lança ClerkOfflineError)
  • Colocar ClerkProvider em volta de <html> (posicionamento incorreto no Core 3)
  • Usar CLERK_WEBHOOK_SECRET em vez de CLERK_WEBHOOK_SIGNING_SECRET
  • Esquecer de adicionar a rota de webhook às rotas públicas no middleware
  • Não selecionar campos seguros de currentUser() antes de passar para o cliente

Sempre verifique o CLAUDE.md para convenções específicas do projeto antes de escrever código.

</red_flags>

Individual skills in this repo

This repo contains 11 individual skills — each has its own dedicated page.

Habilidades Relacionadas