Saltar al contenido
BeeuniBeeuni
Español
Esc
↑↓navegar↵abrir⌘Jvista previa
En esta página

Inicia sesión con Beeuni

Restringe el acceso a tu propia aplicación mediante la identidad de Beeuni con una sola ruta y actúa como el usuario que ha iniciado sesión a través del SDK.

“Iniciar sesión con Beeuni” convierte a Beeuni en el proveedor de identidad de una aplicación que ejecutas: un panel, una herramienta interna o un producto vertical creado sobre Beeuni. Tus usuarios inician sesión con su cuenta de Beeuni, tu servidor sabe quiénes son y cada llamada a Beeuni que hace tu aplicación se ejecuta como ese usuario con sus asignaciones de roles. Todo el flujo está en @beeuni/sdk. Tu aplicación nunca almacena un token de Beeuni en el navegador.

Es OAuth 2.1 estándar (código de autorización + PKCE), servido por la API de Beeuni en api.beeuni.ai.

1. Registra tu aplicación

Ve a Account → Tokens → OAuth apps → Register app o llama al SDK:

const app = await beeuni.iam.oauthClients.create(accountId, {
  name: 'Dashboards',
  client_type: 'confidential',            // 'public' for a browser/native app (PKCE only, no secret)
  redirect_uris: ['https://dashboards.example.com/api/beeuni/auth/callback'],
  scopes: ['profile', 'email', 'beeuni'],
});
// app.client_id, app.client_secret (shown once)

El registro requiere token.create en la cuenta. Los URI de redirección se comparan byte a byte; https es obligatorio excepto en localhost.

Ámbito Concede a la aplicación
profile El id, el correo electrónico y las pertenencias a cuentas del usuario (GET /v1/accounts/me).
email La dirección de correo electrónico (un alias para clientes con formato OIDC).
beeuni Actuar como el usuario en toda la API de Beeuni: proyectos, sesiones, archivos y comprobaciones de IAM. Sin él, el token solo sirve para identificar al usuario.

2. Monta el controlador

// lib/beeuni-auth.ts
import { createBeeuniAuth } from '@beeuni/sdk/server';

export const auth = createBeeuniAuth({
  backendUrl: 'https://api.beeuni.ai/v1',
  clientId: process.env.BEEUNI_OAUTH_CLIENT_ID!,
  clientSecret: process.env.BEEUNI_OAUTH_CLIENT_SECRET,   // omit for a public client
  redirectUri: 'https://dashboards.example.com/api/beeuni/auth/callback',
  cookieSecret: process.env.BEEUNI_AUTH_COOKIE_SECRET!,   // ≥ 32 chars; encrypts the session cookie
});
// app/api/beeuni/auth/[...beeuni]/route.ts  (Next.js App Router)
import { auth } from '@/lib/beeuni-auth';
const handle = (request: Request) => auth.handler(request);
export { handle as GET, handle as POST };

El controlador atiende todas las rutas bajo basePath (derivado del URI de redirección: /api/beeuni/auth arriba):

Ruta Función
/signin?return_to=/path Inicia el inicio de sesión (PKCE S256 + estado en una cookie de 10 minutos) y redirige a Beeuni.
/callback Intercambia el código, establece la cookie de sesión cifrada HttpOnly y redirige a return_to.
/refresh?return_to= Rota el par de tokens y redirige. Lo usa requireViewer.
/signout?return_to= Revoca el token de actualización en Beeuni y elimina la cookie.
/me El usuario que accede en JSON, o 401. Actualiza en la misma operación cuando el token de acceso ha caducado.
/proxy/* Reenvía a la API de Beeuni como el usuario que accede. El backendUrl del SDK del navegador.

return_to siempre está limitado a una ruta del mismo origen.

3. Protege las páginas y actúa como el usuario

// middleware.ts — every page needs a viewer
import { auth } from '@/lib/beeuni-auth';

export async function middleware(request: Request) {
  const gate = await auth.requireViewer(request);
  if (gate.response) return gate.response;   // 302 → /refresh or /signin
}
export const config = { matcher: ['/((?!api/beeuni/auth|_next).*)'] };
// a server component / route handler
const viewer = await auth.viewer(request);       // { userId, email, accounts, scopes, token, expiresAt } | null
const beeuni = await auth.beeuni(request);       // request-scoped client acting as the viewer
const projects = await beeuni.projects.list();
const allowed = await beeuni.iam.can(accountId, viewer!.userId, { action: 'project.write', resourceType: 'project', resourceId });

viewer() es de solo lectura y nunca consume el token de actualización de un solo uso; usa requireViewer() en el middleware para que una página nunca se renderice sin sesión para un usuario cuyo token de actualización siga siendo válido.

4. El navegador

import { createBeeuni } from '@beeuni/sdk';
import { SignInWithBeeuni, useBeeuniViewer } from '@beeuni/sdk/react';

const beeuni = createBeeuni(auth.clientConfig());   // backendUrl = '/api/beeuni/auth/proxy'

function Header() {
  const { status, viewer } = useBeeuniViewer();
  if (status === 'signed-in') return <span>{viewer.email}</span>;
  return <SignInWithBeeuni className="button" />;
}

El cliente del navegador envía un token bearer centinela; /proxy lo sustituye por el token real del usuario en el servidor. useSession, beeuni.project(id).sessions.* y las demás llamadas al SDK funcionan sin cambios a través de él.

Qué ve el usuario

La primera vez, Beeuni muestra una pantalla de consentimiento con el nombre de tu aplicación y los ámbitos. Beeuni recuerda la decisión por usuario y aplicación, así que los siguientes inicios de sesión redirigen directamente de vuelta. Revocar una aplicación elimina todos los tokens que emitió.

Descubrimiento

GET https://api.beeuni.ai/.well-known/oauth-authorization-server (también en /v1/oauth/.well-known/…) publica los endpoints para un cliente OAuth genérico. El SDK no lo necesita: deriva cada endpoint de backendUrl.

Tokens de inicio de sesión para Apps

El código de una App alojada en Beeuni, y de las Apps que esta usa, acepta un segundo tipo de token: un JWT ES256 de corta duración que Beeuni emite para una App. Sin flujo OAuth, sin redirección y sin secreto de cliente.

Valor
Emisor <API origin>/v1/projects/<projectId>, uno por proyecto
Descubrimiento <issuer>/.well-known/openid-configuration y <issuer>/jwks.json, públicos
Audiencia El id de la App a la que está destinado el token
Duración 15 minutos
Declaraciones sub, email, name, picture, groups, group_ids, role, account_id, project_id; el token de un agente añade kind: "agent" y no tiene grupos ni rol

Cada App incluye los valores que verifican sus tokens: app.auth.issuer, app.auth.audience, app.auth.jwks_uri.

import { beeuniToken, beeuniBinding, verifyBeeuniToken, requireBeeuniMember } from '@beeuni/sdk';

// In the App's browser code: a token fetcher for this App, or an App it uses.
const forThisApp = beeuniToken();
const forDb = beeuniToken({ audience: 'db' });
const db = beeuniBinding('db');   // { url: '<origin>/_beeuni/apps/db', token: forDb }

// On a server that receives the token:
const member = await verifyBeeuniToken(bearer, {
  issuer: app.auth.issuer,
  audience: app.auth.audience,
  jwks: app.auth.jwks_uri,
});
requireBeeuniMember(member, { roles: ['owner', 'admin'] });

En una App de servidor, Beeuni inyecta BEEUNI_AUTH_ISSUER (el emisor del proyecto), BEEUNI_AUTH_AUDIENCE (el id de la propia App) y BEEUNI_AUTH_JWKS (el conjunto de claves del proyecto, como un URI data:), así que verifyBeeuniToken(bearer) no necesita opciones. No establezcas BEEUNI_AUTH_* por tu cuenta: el prefijo BEEUNI_ está reservado y beeuni validate lo rechaza.

verifyBeeuniToken rechaza un token cuando no se ha establecido ninguna audiencia (la opción o BEEUNI_AUTH_AUDIENCE): una clave del proyecto firma los tokens de todas las Apps del proyecto, así que aud es lo que impide aceptar el token de otra App. Pasa audience: false solo para aceptar un token destinado a cualquier App del proyecto.

beeuniToken lee GET /_beeuni/token?audience=<slug or id> en el origen propio de la App. La audiencia es la propia App (por defecto) o una App que esta usa (beeuni apps link <app> --uses <other>); cualquier otra devuelve 403 app_not_linked. Un miembro, un script o un agente obtiene uno a través de la API en su lugar: beeuni.project(projectId).apps.token(appId) o beeuni apps token <app>. El contrato completo, el montaje de los bindings y la configuración del backend de Convex: SDK → Apps y Apps → Apps que usa una App.

¿Te ha resultado útil esta página?