Adaptadores de autenticação personalizados
O Rebase inclui sua própria autenticação — configure-a aqui. Esta página trata do outro caso: um provedor de identidade que você já utiliza ou pelo qual já paga.
Adaptadores de autenticação personalizados
Seção intitulada “Adaptadores de autenticação personalizados”O Rebase permite a substituição completa do sistema de autenticação integrado por meio de uma arquitetura de autenticação plugável. Isso desacopla a verificação de autenticação do banco de dados e das camadas REST/WebSocket, permitindo uma integração perfeita com provedores externos como Clerk, Auth0, Firebase Auth ou serviços de identidade JWT personalizados.
O contrato AuthAdapter
Seção intitulada “O contrato AuthAdapter”Você pode implementar a interface AuthAdapter diretamente para obter controle total. A definição da interface é a seguinte:
import { Hono } from "hono";import type { HonoEnv } from "@rebasepro/server";import { AuthenticatedUser, AuthAdapterCapabilities, UserManagementAdapter, UserCreationPrepareResult, UserCreationFinalizeResult } from "@rebasepro/types";
export interface AuthAdapter { /** Unique identifier for this auth adapter (e.g., "clerk", "custom") */ readonly id: string;
/** * Verifies an incoming HTTP request and returns the authenticated user payload. * Called by Hono authentication middleware on every REST endpoint. */ verifyRequest(request: Request): Promise<AuthenticatedUser | null>;
/** * Verifies a raw token string (e.g. for WebSocket connection handshake phase 1). * If omitted, a synthetic request is automatically constructed. */ verifyToken?(token: string): Promise<AuthenticatedUser | null>;
/** Optional user management operations (CRUD) for the panel */ userManagement?: UserManagementAdapter;
/** Optional: Mount adapter-specific custom public routes (e.g. callback paths) */ createAuthRoutes?(): Hono<any, any, any> | undefined;
/** Optional: Mount adapter-specific admin-only routes */ createAdminRoutes?(): Hono<any, any, any> | undefined;
/** Advertise supported capabilities (to customize what the panel shows) */ getCapabilities(): AuthAdapterCapabilities | Promise<AuthAdapterCapabilities>;
/** Lifecycle hooks called during backend start and graceful shutdown */ initialize?(): Promise<void>; destroy?(): Promise<void>;
/** Custom user lifecycle hooks (e.g., hash passwords before collection writes) */ prepareUserCreation?( values: Record<string, unknown>, collectionAuth?: unknown ): Promise<UserCreationPrepareResult>;
finalizeUserCreation?( entity: { id: string; values: Record<string, unknown> }, clearPassword?: string ): Promise<UserCreationFinalizeResult>;
/** Static service key to bypass checks for server-to-server calls */ serviceKey?: string;}O payload do usuário autenticado
Seção intitulada “O payload do usuário autenticado”Independentemente do provedor de autenticação externo escolhido, seu adaptador deve resolver verificações de token bem-sucedidas em um objeto AuthenticatedUser uniforme. O Rebase RLS Scope Injector mapeia esses valores diretamente para variáveis de sessão do PostgreSQL dentro de transações:
export interface AuthenticatedUser { uid: string; // Maps to pg local 'app.user_id' -> rebase.uid() email: string; // User email address displayName?: string | null; // Optional display name photoUrl?: string | null; // Optional avatar URL roles: string[]; // Maps to pg local 'app.user_roles' -> rebase.roles() isAdmin: boolean; // Grants global superuser privileges if true rawToken?: string; // The original token string (for downstream forwarding) claims?: Record<string, any>; // Custom claims/metadata (available in rebase.jwt())}Integração rápida via createCustomAuthAdapter
Seção intitulada “Integração rápida via createCustomAuthAdapter”Para cenários padrão (como a validação de JWTs de um serviço de terceiros), você pode usar o utilitário createCustomAuthAdapter. Esse utilitário lida com os padrões de capacidades e implementa a validação de token de WebSocket pronta para uso, encapsulando sua implementação de verifyRequest.
Exemplo: Integrando com o Clerk
Seção intitulada “Exemplo: Integrando com o Clerk”Para conectar um backend Rebase ao Clerk, você pode verificar tokens JWT do Clerk usando o JSON Web Key Set (JWKS) do Clerk:
import { initializeRebaseBackend } from "@rebasepro/server";import { createCustomAuthAdapter } from "@rebasepro/server";import { createRemoteJWKSet, jwtVerify } from "jose";
// Clerk JWKS URLconst CLERK_JWKS_URL = "https://clerk.your-domain.com/.well-known/jwks.json";const JWKS = createRemoteJWKSet(new URL(CLERK_JWKS_URL));
const clerkAuthAdapter = createCustomAuthAdapter({ serviceKey: process.env.REBASE_SERVICE_KEY, verifyRequest: async (request) => { const authHeader = request.headers.get("Authorization"); const token = authHeader?.replace("Bearer ", ""); if (!token) return null;
try { // Verify Clerk JWT token against JWKS const { payload } = await jwtVerify(token, JWKS);
const metadata = payload.metadata as Record<string, unknown> | undefined; const roles = Array.isArray(metadata?.roles) ? metadata.roles as string[] : [];
return { uid: payload.sub!, email: (payload as Record<string, unknown>).email as string || "", displayName: (payload as Record<string, unknown>).name as string || null, roles: roles, isAdmin: roles.includes("admin"), claims: payload as Record<string, unknown> }; } catch (error) { console.error("Clerk token verification failed:", error); return null; // Fail-closed } }, capabilities: { hasBuiltInAuthRoutes: false, // Login is managed by Clerk UI emailPasswordLogin: false, registrationEnabled: false, passwordReset: false, profileUpdate: false, sessionManagement: false }});
const backend = await initializeRebaseBackend({ auth: clerkAuthAdapter, // ...});Exemplo: Integrando com o Firebase Auth
Seção intitulada “Exemplo: Integrando com o Firebase Auth”Para verificar tokens do Firebase Auth usando os certificados públicos do Firebase:
import { initializeRebaseBackend } from "@rebasepro/server";import { createCustomAuthAdapter } from "@rebasepro/server";import { createRemoteJWKSet, jwtVerify } from "jose";
const FIREBASE_JWKS_URL = "https://www.googleapis.com/robot/v1/metadata/jwk/securetoken@system.gserviceaccount.com";const JWKS = createRemoteJWKSet(new URL(FIREBASE_JWKS_URL));const FIREBASE_PROJECT_ID = "my-firebase-project-id";
const firebaseAuthAdapter = createCustomAuthAdapter({ serviceKey: process.env.REBASE_SERVICE_KEY, verifyRequest: async (request) => { const authHeader = request.headers.get("Authorization"); const token = authHeader?.replace("Bearer ", ""); if (!token) return null;
try { const { payload } = await jwtVerify(token, JWKS, { issuer: `https://securetoken.google.com/${FIREBASE_PROJECT_ID}`, audience: FIREBASE_PROJECT_ID });
const roles = Array.isArray((payload as Record<string, unknown>).roles) ? (payload as Record<string, unknown>).roles as string[] : [];
return { uid: payload.sub!, email: (payload as Record<string, unknown>).email as string || "", displayName: (payload as Record<string, unknown>).name as string || null, photoUrl: (payload as Record<string, unknown>).picture as string || null, roles: roles, isAdmin: roles.includes("admin"), claims: payload as Record<string, unknown> }; } catch (error) { console.error("Firebase token verification failed:", error); return null; } }});
const backend = await initializeRebaseBackend({ auth: firebaseAuthAdapter, // ...});Montando rotas de autenticação e ações do painel
Seção intitulada “Montando rotas de autenticação e ações do painel”Se o seu provedor de autenticação personalizado exigir a montagem de endpoints de redirecionamento (como rotas de callback OAuth ou fluxos de login SAML), implemente o método createAuthRoutes no seu adaptador:
const myOauthAdapter: AuthAdapter = { id: "custom-oauth", verifyRequest: async (req) => ({ // validate the token, then return the caller uid: "…", email: "user@example.com", roles: [], isAdmin: false }), getCapabilities: () => ({ hasBuiltInAuthRoutes: true, emailPasswordLogin: false, registrationEnabled: false, passwordReset: false, adminPasswordReset: false, sessionManagement: false, profileUpdate: false, emailVerification: false, magicLink: false, anonymousLogin: false, enabledProviders: [] }), createAuthRoutes: () => { const app = new Hono<HonoEnv>();
// Mounted automatically under /api/auth/callback app.get("/callback", async (c) => { const code = c.req.query("code"); // Exchange code for provider tokens and set cookies/redirect return c.redirect("/dashboard"); });
return app; }};Se você deseja permitir operações CRUD de usuário diretamente no painel, implemente o helper userManagement nas opções do adaptador, que fornece hooks para listUsers, createUser, updateUser e deleteUser.
Próximos passos
Seção intitulada “Próximos passos”- Authentication — a configuração do provedor integrado
- Endpoints and tokens — as rotas que um adaptador precisa atender
- Security Rules (RLS) — para que são usadas as claims retornadas por um adaptador