Nuxt
Moduł dla Nuxt — dwie linijki konfiguracji, strona powrotu, której nie piszesz, i middleware chroniący stronę z jej własnych metadanych.
@kleora-io/nuxt to SDK przeglądarkowe w formie modułu Nuxt 4: trzyma
klienta, dodaje stronę powrotu, rejestruje middleware tras i daje uwierzytelniony
$fetch.
npm install @kleora-io/nuxt
1. Zarejestruj moduł
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@kleora-io/nuxt'],
kleora: { issuer: '<issuer>', clientId: '<client_id>' },
})
issuer i clientId to jedyne wymagane opcje — pusta wartość rzuca błędem przy
starcie aplikacji, nazywając zarówno opcję, jak i zmienną środowiskową, która by
ją ustawiła. Nie ma tu redirectUri, bo moduł domyślnie ustawia go na własną stronę
powrotu w origin, z którego serwowana jest witryna: /auth/callback. To
nadal jest adres, który rejestrujesz na kliencie, dokładnie w tej postaci.
Osiem opcji można podać ze środowiska zamiast z pliku konfiguracyjnego — tak jeden build obsługuje sandbox i produkcję:
| Opcja | Zmienna |
|---|---|
issuer | NUXT_PUBLIC_KLEORA_ISSUER |
clientId | NUXT_PUBLIC_KLEORA_CLIENT_ID |
redirectUri | NUXT_PUBLIC_KLEORA_REDIRECT_URI |
scope | NUXT_PUBLIC_KLEORA_SCOPE |
audience | NUXT_PUBLIC_KLEORA_AUDIENCE |
tenant | NUXT_PUBLIC_KLEORA_TENANT |
storage | NUXT_PUBLIC_KLEORA_STORAGE |
apiBase | NUXT_PUBLIC_API_BASE |
Dziewiąta, callbackPath, działa wyłącznie w czasie budowania: moduł montuje pod
nią trasę podczas builda, więc zmienna środowiskowa przesunęłaby miejsce, gdzie
ląduje przeglądarka, nie przesuwając strony, która to obsługuje. Ustaw ją w
nuxt.config i trzymaj równą ścieżce z redirectUri.
2. Zaloguj się ze strony
<!-- app/pages/index.vue -->
<script setup lang="ts">
const { isAuthenticated, isLoading, login, logout } = useKleora()
const user = useKleoraUser()
</script>
<template>
<p v-if="isLoading">Wczytywanie…</p>
<button v-else-if="!isAuthenticated" @click="login()">Zaloguj się</button>
<div v-else>
<p>{{ user?.sub }} · {{ user?.email }} · {{ user?.tenant }}</p>
<button @click="logout({ returnTo: '/' })">Wyloguj się</button>
</div>
</template>
logout() bez argumentu odsyła przeglądarkę na korzeń witryny, więc / w Twoim
origin musi być jednym z zarejestrowanych adresów po wylogowaniu.
3. Chroń stronę
Moduł rejestruje globalny middleware o nazwie kleora, a ten działa tylko
na stronach, które o to proszą:
<script setup lang="ts">
definePageMeta({ auth: true })
</script>
Ochrona leży w metadanych samej strony, więc strona nie traci jej przez to, że ktoś zapomniał dopisać ją do listy gdzie indziej. Middleware działa po stronie klienta: renderowanie na serwerze oddaje szkielet dla niezalogowanego i nigdy nie przekierowuje.
4. Wołaj API z dołączonym tokenem
const api = useKleoraApi()
const invoices = await api('/invoices')
$kleoraApi to instancja $fetch z apiBase jako bazowym adresem i tokenem
w każdym żądaniu. 401 jest ponawiane dokładnie raz, z wymuszonym odświeżeniem
— więc odrzucony token nigdy nie leci po prostu drugi raz — a błąd przychodzi
jako ApiError z dokumentem problemu RFC 9457, nie jako sam kod statusu.
Co daje moduł
| Eksport | Czym jest |
|---|---|
useKleora() | Kontekst: client, user, isAuthenticated, isLoading, hasLikelySession, login, logout, getAccessToken, restore, settle. |
useKleoraUser() | Ref z zalogowanym użytkownikiem albo null. |
useKleoraApi() | Uwierzytelniona instancja $fetch jako composable. |
decideSessionRender() | Odwzorowuje { hasMarker, isLoading, isAuthenticated } na 'shell' albo 'redirect' — dla layoutu, który inaczej by mignął. |
middleware kleora-auth | Globalny, wyzwalany przez definePageMeta({ auth: true }). |
/auth/callback | Strona dodawana przez moduł — chyba że Twoja aplikacja ma już własną pod tą ścieżką. |