Express
Sprawdzanie tokenu dostępu we własnym API — middleware, uprawnienia i trzy odpowiedzi, jakie może mieć odmowa.
Druga połowa każdej strony w tej sekcji: przeglądarka ma token, a Twoje API musi zdecydować, co on znaczy. Weryfikacja jest offline — token to podpisany JWT, Twoje API sprawdza go względem zestawu kluczy publikowanego przez Twój issuer i nie pyta nas o nic przy każdym żądaniu.
npm install @kleora-io/node
Jedna zależność w czasie działania, biblioteka JOSE. Express i Fastify są opcjonalnymi peerami, więc paczka instaluje się bez obu.
1. Najpierw uwierzytelnienie, potem autoryzacja
import express from 'express'
import { express as kleora, requirePermission } from '@kleora-io/node'
const app = express()
app.use(
kleora({
issuer: process.env.KLEORA_ISSUER!,
audience: 'https://api.example.com',
}),
)
app.get('/invoices', requirePermission('invoices:read'), (req, res) => {
res.json({ tenant: req.kleora.tenant })
})
Middleware weryfikuje token i ustawia req.kleora na jego claimy.
requirePermission czyta req.kleora.permissions — a te są już w tokenie,
więc sprawdzenie kosztuje tyle, co przejrzenie listy, a nie zapytanie do nas.
2. Co podać jako audience
Claim aud tokenu dostępu to [client_id], a po ustawieniu na środowisku
własnego api_audience — [client_id, api_audience]. Świeże środowisko nie ma
go wcale, więc dopóki go nie ustawisz, podawaj identyfikator klienta, a
potem własny identyfikator API.
3. Trzy odpowiedzi, jakie może mieć odmowa
| Sytuacja | Odpowiedź |
|---|---|
Brak nagłówka Authorization albo token, który się nie zweryfikował | 401, dokument problemu unauthenticated |
| Token poprawny, ale brakuje uprawnienia | 403 insufficient-permission |
| Zestawu kluczy issuera w ogóle nie da się odczytać | 503 issuer-unavailable |
Treść 401 mówi tylko tyle, że żądanie nie zostało uwierzytelnione. Powód —
token wygasł, zły audience, zły podpis — idzie do opcji logger, czyli tam,
gdzie przydaje się Tobie, a nie temu, kto próbuje zgadywać. 503 znaczy więcej,
niż wygląda: bez niego nasza awaria mówiłaby każdemu z Twoich użytkowników, że
jego token jest zły, i odsyłała go do issuera, który i tak już leży.
Wszystko inne to Twoja usługa skonfigurowana źle, i paczka nie wybiera za Ciebie
statusu: w Express dostaje to next(error) i odpowiada Twój własny handler
błędów.
requirePermission odpowiada 401, a nie 403, kiedy req.kleora w ogóle
nie ma — trasa, na której zabrakło middleware uwierzytelniającego, to nie
problem z uprawnieniami.
4. Co dokładnie sprawdza weryfikator
Nagłówek typ równy at+jwt, podpis ES256 względem zestawu kluczy issuera,
iss dokładnie, aud zawierające Twój audience, exp i iat z tolerancją 60
sekund oraz to, że claim env tokenu zgadza się ze skonfigurowanym issuerem —
więc token z sandboksa nie zadowoli po cichu produkcyjnego API.
Zestaw kluczy pobierany jest raz na issuer i trzymany tak długo, jak mówi jego
Cache-Control. kid, którego cache nie zna, wywołuje jedno ponowne pobranie,
nie częściej niż raz na minutę; nieudane pobranie serwuje zapamiętany zestaw do
dwukrotności jego TTL, a potem odmawia. Klucze podpisujące są publikowane, zanim
zaczną być używane, więc rotacja w locie trafia na kid, który już jest w
cache'u.
Fastify i cała reszta
fastify({ issuer, audience }) to ta sama wtyczka: dekoruje request.kleora i
daje te same trzy odpowiedzi. Rejestruje się bez enkapsulacji, bo zarejestrowanie
wtyczki uwierzytelniającej w korzeniu nigdy nie znaczy „tylko trasy wewnątrz tej
wtyczki”.
Dla API w Pythonie to samo sprawdzenie i te same reguły ma kleora —
opisuje je Instalacja SDK.