Aller au contenu
BeeuniBeeuni
Français
Esc
↑↓naviguer↵ouvrir⌘Japerçu
Sur cette page

Se connecter avec Beeuni

Protégez l’accès à votre application avec l’identité Beeuni via une seule route, et agissez au nom de l’utilisateur connecté grâce au SDK.

« Se connecter avec Beeuni » fait de Beeuni le fournisseur d’identité d’une application que vous exploitez : un tableau de bord, un outil interne, un produit vertical construit sur Beeuni. Vos utilisateurs se connectent avec leur compte Beeuni, votre serveur sait qui ils sont, et chaque appel Beeuni effectué par votre application s’exécute au nom de cet utilisateur avec ses attributions de rôles. Tout le flux se trouve dans @beeuni/sdk. Votre application ne stocke jamais de jeton Beeuni dans le navigateur.

Il s’agit du protocole standard OAuth 2.1 (code d’autorisation + PKCE), fourni par l’API Beeuni à l’adresse api.beeuni.ai.

1. Enregistrer votre application

Accédez à Account → Tokens → OAuth apps → Register app, ou appelez le 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)

L’enregistrement nécessite token.create sur le compte. Les URI de redirection sont comparées octet par octet ; https est obligatoire, sauf sur localhost.

Portée Accorde à l’application
profile L’identifiant, l’adresse e-mail et les appartenances aux comptes de l’utilisateur (GET /v1/accounts/me).
email L’adresse e-mail (un alias pour les clients au format OIDC).
beeuni La possibilité d’agir au nom de l’utilisateur sur toute l’API Beeuni — projets, sessions, fichiers, vérifications IAM. Sans cette portée, le jeton sert uniquement à l’identité.

2. Monter le gestionnaire

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

Le gestionnaire dessert toutes les routes sous basePath (dérivé de l’URI de redirection — /api/beeuni/auth ci-dessus) :

Chemin Action
/signin?return_to=/path Lance la connexion (PKCE S256 + état dans un cookie de 10 minutes) et redirige vers Beeuni.
/callback Échange le code, définit le cookie de session chiffré HttpOnly, puis redirige vers return_to.
/refresh?return_to= Renouvelle la paire de jetons et redirige. Utilisé par requireViewer.
/signout?return_to= Révoque le jeton de renouvellement auprès de Beeuni et supprime le cookie.
/me Le visiteur au format JSON, ou 401. Renouvelle le jeton à la volée lorsque le jeton d’accès a expiré.
/proxy/* Transmet à l’API Beeuni au nom du visiteur. Le backendUrl du SDK navigateur.

return_to est toujours limité à un chemin de même origine.

3. Protéger les pages et agir au nom de l’utilisateur

// 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() est en lecture seule et ne consomme jamais le jeton de renouvellement à usage unique ; utilisez requireViewer() dans le middleware pour qu’une page ne s’affiche jamais comme déconnectée pour un utilisateur dont le jeton de renouvellement est encore valide.

4. Le navigateur

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

Le client navigateur envoie un jeton bearer sentinelle ; /proxy le remplace par le véritable jeton du visiteur sur le serveur. useSession, beeuni.project(id).sessions.* et tous les autres appels du SDK fonctionnent sans modification par son intermédiaire.

Ce que voit l’utilisateur

La première fois, Beeuni affiche un écran de consentement indiquant le nom de votre application et les portées. Beeuni mémorise la décision pour chaque utilisateur et chaque application ; les connexions suivantes redirigent donc directement vers votre application. Révoquer une application supprime tous les jetons qu’elle a émis.

Découverte

GET https://api.beeuni.ai/.well-known/oauth-authorization-server (également sous /v1/oauth/.well-known/…) publie les points de terminaison pour un client OAuth générique. Le SDK n’en a pas besoin — il déduit chaque point de terminaison de backendUrl.

Jetons de connexion pour les Apps

Le code d’une App hébergée par Beeuni, ainsi que les Apps qu’elle utilise, accepte un second type de jeton : un JWT ES256 court que Beeuni émet pour une seule App. Aucun flux OAuth, aucune redirection, aucun secret client.

Valeur
Émetteur <API origin>/v1/projects/<projectId>, un par projet
Découverte <issuer>/.well-known/openid-configuration et <issuer>/jwks.json, publics
Audience L’identifiant de l’App à laquelle le jeton est destiné
Durée de validité 15 minutes
Claims sub, email, name, picture, groups, group_ids, role, account_id, project_id ; le jeton d’un agent ajoute kind: "agent" et ne contient ni groupes ni rôle

Chaque App contient les valeurs permettant de vérifier ses jetons : 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'] });

Dans une App serveur, Beeuni injecte BEEUNI_AUTH_ISSUER (l’émetteur du projet), BEEUNI_AUTH_AUDIENCE (l’identifiant de l’App elle-même) et BEEUNI_AUTH_JWKS (le jeu de clés du projet, sous forme d’URI data:), de sorte que verifyBeeuniToken(bearer) ne nécessite aucune option. Ne définissez pas BEEUNI_AUTH_* vous-même : le préfixe BEEUNI_ est réservé et beeuni validate le rejette.

verifyBeeuniToken refuse un jeton lorsqu’aucune audience n’est définie (via l’option ou BEEUNI_AUTH_AUDIENCE) : une seule clé de projet signe les jetons de toutes les Apps du projet ; c’est donc aud qui empêche l’utilisation du jeton d’une autre App. Passez audience: false uniquement pour accepter un jeton destiné à n’importe quelle App du projet.

beeuniToken lit GET /_beeuni/token?audience=<slug or id> sur l’origine propre de l’App. L’audience est l’App elle-même (par défaut) ou une App qu’elle utilise (beeuni apps link <app> --uses <other>) ; toute autre audience reçoit 403 app_not_linked. Un membre, un script ou un agent en émet plutôt un via l’API : beeuni.project(projectId).apps.token(appId), ou beeuni apps token <app>. Le contrat complet, le montage des bindings et la configuration du backend Convex : SDK → Apps et Apps → Apps utilisées par une App.

Cette page vous a-t-elle été utile ?