Пријавите се помоћу Beeuni
Ограничите приступ својој апликацији помоћу Beeuni идентитета уз једну руту и делујте у име пријављеног корисника путем SDK-а.
„Пријављивање преко Beeuni“ чини Beeuni добављачем идентитета за апликацију коју покрећете:
контролну таблу, интерни алат или специјализован производ изграђен на Beeuni. Корисници
се пријављују својим Beeuni налогом, ваш сервер зна ко су, а сваки
Beeuni позив из ваше апликације извршава се као тај корисник, са његовим
додељеним улогама. Цео ток је у @beeuni/sdk. Ваша апликација никада не чува
Beeuni токен у прегледачу.
То је стандардни OAuth 2.1 (ауторизациони код + PKCE) који Beeuni API пружа
на api.beeuni.ai.
1. Региструјте своју апликацију
Идите на Account → Tokens → OAuth apps → Register app или позовите 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)
За регистрацију је потребно token.create на налогу. URI адресе за преусмеравање пореде се
бајт по бајт; https је обавезан осим на localhost.
| Опсег | Омогућава апликацији |
|---|---|
profile |
ID корисника, адресу е-поште и чланства у налозима (GET /v1/accounts/me). |
email |
Адресу е-поште (алијас за клијенте који прате OIDC структуру). |
beeuni |
Деловање као корисник на целом Beeuni API-ју — пројекти, сесије, датотеке, IAM провере. Без тога токен служи само за идентитет. |
2. Повежите обрађивач
// 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 };
Обрађивач опслужује сваку руту под basePath (изведено из URI адресе
за преусмеравање — /api/beeuni/auth изнад):
| Путања | Радња |
|---|---|
/signin?return_to=/path |
Покреће пријављивање (PKCE S256 + стање у колачићу који траје 10 минута) и преусмерава на Beeuni. |
/callback |
Размењује код, поставља шифровани колачић сесије HttpOnly и преусмерава на return_to. |
/refresh?return_to= |
Ротира пар токена и преусмерава. Користи га requireViewer. |
/signout?return_to= |
Опозива токен за освежавање у Beeuni и брише колачић. |
/me |
Посетилац као JSON или 401. Освежава токен током обраде ако је приступни токен истекао. |
/proxy/* |
Прослеђује Beeuni API-ју као посетилац. backendUrl SDK-а за прегледач. |
return_to је увек ограничен на путању истог порекла.
3. Ограничите приступ страницама и делујте као корисник
// 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() служи само за читање и никада не троши једнократни токен за освежавање; користите
requireViewer() у посредничком слоју да се страница никада не прикаже као за одјављеног корисника
ако је његов токен за освежавање још важећи.
4. Прегледач
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" />;
}
Клијент у прегледачу шаље заменски bearer токен; /proxy га на серверу замењује
стварним токеном посетиоца. useSession, beeuni.project(id).sessions.* и
сви остали SDK позиви раде непромењено преко њега.
Шта корисник види
Први пут Beeuni приказује екран за сагласност са називом ваше апликације и опсезима. Beeuni памти одлуку за сваког корисника и апликацију, па каснија пријављивања преусмеравају директно назад. Опозив апликације брише сваки токен који је издала.
Откривање
GET https://api.beeuni.ai/.well-known/oauth-authorization-server (такође
под /v1/oauth/.well-known/…) објављује крајње тачке за општи OAuth
клијент. SDK-у то није потребно — сваку крајњу тачку изводи из backendUrl.
Токени за пријављивање за апликације
Код у апликацији коју хостује Beeuni и апликацијама које она користи прихвата другу врсту токена: кратак ES256 JWT који Beeuni издаје за једну апликацију. Без OAuth тока, без преусмеравања, без тајне клијента.
| Вредност | |
|---|---|
| Издавалац | <API origin>/v1/projects/<projectId>, један по пројекту |
| Откривање | <issuer>/.well-known/openid-configuration и <issuer>/jwks.json, јавно |
| Публика | ID апликације којој је токен намењен |
| Рок важења | 15 минута |
| Тврдње | sub, email, name, picture, groups, group_ids, role, account_id, project_id; токен агента додаје kind: "agent" и нема групе ни улогу |
Свака апликација садржи вредности за проверу својих токена: 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'] });
У серверској апликацији Beeuni убацује BEEUNI_AUTH_ISSUER (издаваоца пројекта),
BEEUNI_AUTH_AUDIENCE (ID саме апликације) и BEEUNI_AUTH_JWKS (скуп кључева
пројекта, као data: URI), па verifyBeeuniToken(bearer) не захтева опције.
Немојте сами постављати BEEUNI_AUTH_*: префикс BEEUNI_ је резервисан и
beeuni validate га одбија.
verifyBeeuniToken одбија токен када публика није постављена (опција или
BEEUNI_AUTH_AUDIENCE): један кључ пројекта потписује токене сваке апликације у
пројекту, па aud спречава прихватање токена друге апликације. Проследите
audience: false само ако желите да прихватите токен за било коју апликацију пројекта.
beeuniToken чита GET /_beeuni/token?audience=<slug or id> на сопственом
пореклу апликације. Публика је сама апликација (подразумевано) или апликација коју она користи
(beeuni apps link <app> --uses <other>); за било коју другу одговор је
403 app_not_linked. Члан, скрипта или агент уместо тога издаје токен преко API-ја:
beeuni.project(projectId).apps.token(appId) или
beeuni apps token <app>. Потпун уговор, повезивање веза и
подешавање Convex позадинског система: SDK → Апликације и
Апликације → Апликације које апликација користи.