Vai al contenuto
BeeuniBeeuni
Italiano
Esc
↑↓naviga↵apri⌘Janteprima
In questa pagina

Accedi con Beeuni

Proteggi l'accesso alla tua app con l'identità Beeuni tramite un'unica route e agisci come l'utente autenticato tramite l'SDK.

“Accedi con Beeuni” rende Beeuni il provider di identità per un’app che gestisci: una dashboard, uno strumento interno, un prodotto verticale basato su Beeuni. I tuoi utenti accedono con il loro account Beeuni, il tuo server sa chi sono e ogni chiamata Beeuni effettuata dalla tua app viene eseguita come quell’utente, con le sue assegnazioni di ruolo. L’intero flusso risiede in @beeuni/sdk. La tua app non memorizza mai un token Beeuni nel browser.

È OAuth 2.1 standard (codice di autorizzazione + PKCE), fornito dall’API Beeuni su api.beeuni.ai.

1. Registra la tua app

Vai a Account → Tokens → OAuth apps → Register app, oppure chiama l’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)

La registrazione richiede token.create sull’account. Gli URI di reindirizzamento vengono confrontati byte per byte; https è obbligatorio tranne su localhost.

Ambito Concede all’app
profile L’id, l’email e le appartenenze agli account dell’utente (GET /v1/accounts/me).
email L’indirizzo email (un alias per i client conformi a OIDC).
beeuni La possibilità di agire come l’utente sull’intera API Beeuni: progetti, sessioni, file, verifiche IAM. Senza questo ambito, il token serve solo per l’identità.

2. Monta l’handler

// 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 };

L’handler gestisce ogni route sotto basePath (derivato dall’URI di reindirizzamento: /api/beeuni/auth qui sopra):

Percorso Funzione
/signin?return_to=/path Avvia l’accesso (PKCE S256 + state in un cookie di 10 minuti) e reindirizza a Beeuni.
/callback Scambia il codice, imposta il cookie di sessione crittografato HttpOnly e reindirizza a return_to.
/refresh?return_to= Ruota la coppia di token e reindirizza. Usato da requireViewer.
/signout?return_to= Revoca il token di aggiornamento su Beeuni ed elimina il cookie.
/me L’utente corrente in formato JSON, oppure 401. Esegue l’aggiornamento direttamente quando il token di accesso è scaduto.
/proxy/* Inoltra all’API Beeuni come utente corrente. Il backendUrl dell’SDK per il browser.

return_to è sempre limitato a un percorso della stessa origine.

3. Proteggi l’accesso alle pagine e agisci come l’utente

// 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() è di sola lettura e non consuma mai il token di aggiornamento monouso; usa requireViewer() nel middleware affinché una pagina non venga mai renderizzata come se l’utente non fosse autenticato quando il suo token di aggiornamento è ancora valido.

4. Il browser

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" />;
}

Il client del browser invia un bearer sentinella; /proxy lo sostituisce con il token reale dell’utente corrente sul server. useSession, beeuni.project(id).sessions.* e ogni altra chiamata SDK funzionano senza modifiche tramite questo meccanismo.

Cosa vede l’utente

La prima volta, Beeuni mostra una schermata di consenso che indica il nome della tua app e gli ambiti. Beeuni ricorda la decisione per ogni utente e app, quindi gli accessi successivi reindirizzano direttamente all’app. La revoca di un’app elimina tutti i token che ha emesso.

Discovery

GET https://api.beeuni.ai/.well-known/oauth-authorization-server (anche sotto /v1/oauth/.well-known/…) pubblica gli endpoint per un client OAuth generico. L’SDK non ne ha bisogno: ricava ogni endpoint da backendUrl.

Token di accesso per le Apps

Il codice in un’App ospitata da Beeuni e nelle Apps che utilizza accetta un secondo tipo di token: un JWT ES256 breve che Beeuni emette per una singola App. Nessun flusso OAuth, nessun reindirizzamento, nessun segreto client.

Valore
Emittente <API origin>/v1/projects/<projectId>, uno per progetto
Discovery <issuer>/.well-known/openid-configuration e <issuer>/jwks.json, pubblici
Destinatario L’id dell’App a cui è destinato il token
Durata 15 minuti
Claim sub, email, name, picture, groups, group_ids, role, account_id, project_id; il token di un agente aggiunge kind: "agent" e non ha gruppi né ruolo

Ogni App contiene i valori per verificare i propri token: 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'] });

In un’App server, Beeuni inietta BEEUNI_AUTH_ISSUER (l’emittente del progetto), BEEUNI_AUTH_AUDIENCE (l’id dell’App stessa) e BEEUNI_AUTH_JWKS (il set di chiavi del progetto, come URI data:), quindi verifyBeeuniToken(bearer) non richiede opzioni. Non impostare BEEUNI_AUTH_* autonomamente: il prefisso BEEUNI_ è riservato e beeuni validate lo rifiuta.

verifyBeeuniToken rifiuta un token quando non è impostato alcun destinatario (tramite l’opzione o BEEUNI_AUTH_AUDIENCE): una sola chiave del progetto firma i token di tutte le Apps del progetto, quindi è aud a impedire l’accesso con il token di un’altra App. Passa audience: false solo per accettare un token destinato a qualsiasi App del progetto.

beeuniToken legge GET /_beeuni/token?audience=<slug or id> sull’origine dell’App stessa. Il destinatario è l’App stessa (per impostazione predefinita) o un’App che utilizza (beeuni apps link <app> --uses <other>); per qualsiasi altro destinatario, la risposta è 403 app_not_linked. Un membro, uno script o un agente ne emette invece uno tramite l’API: beeuni.project(projectId).apps.token(appId), oppure beeuni apps token <app>. Il contratto completo, il montaggio dei binding e la configurazione del backend Convex: SDK → Apps e Apps → Apps utilizzate da un’App.

Questa pagina ti è stata utile?