Kinde, uwierzytelnianie plus rzeczy, które i tak byś dokładał
Logowanie w aplikacji rzadko kończy się na logowaniu. Po miesiącu potrzebne są organizacje, bo klient chce zaprosić zespół. Po dwóch role i uprawnienia. Po trzech flagi funkcji, żeby wypuścić coś tylko wybranym klientom.
Kinde umieszcza te rzeczy w jednej usłudze, zamiast zostawiać je do złożenia z osobnych narzędzi. To główny powód, dla którego warto go rozważyć obok bardziej znanych rozwiązań, a przy okazji odpowiedź na pytanie, dlaczego darmowy próg jest tu wyższy niż u konkurencji.
Co jest w komplecie
Podstawa to standardowe sposoby logowania: hasło, logowanie przez zewnętrznych dostawców, przesyłanie odnośnika na pocztę, klucze dostępu i drugi składnik. Nic zaskakującego i tak powinno być.
Ciekawsze zaczyna się przy organizacjach. Użytkownik może należeć do kilku, mieć w każdej inne role, a aplikacja dostaje w tokenie informację, w kontekście której organizacji działa. To jest dokładnie ten mechanizm, który przy własnej implementacji zajmuje dwa tygodnie i zawsze zawiera błąd przy przełączaniu kontekstu.
Flagi funkcji są tu drugim wyróżnikiem. Wartość flagi przychodzi razem z tokenem, więc nie potrzeba osobnego wywołania do innej usługi przy każdym renderowaniu. Flagę da się ustawić globalnie, dla organizacji albo dla pojedynczego użytkownika.
Trzecim elementem są uprawnienia maszynowe, czyli dostęp dla usług, a nie dla ludzi. Przy zapleczu złożonym z kilku usług to potrzebne wcześniej, niż większość zespołów zakłada, bo pierwsze zadanie w tle wywołujące własny interfejs programistyczny musi się jakoś uwierzytelnić.
Integracja z aplikacją
pnpm add @kinde-oss/kinde-auth-nextjsimport { getKindeServerSession } from '@kinde-oss/kinde-auth-nextjs/server'
export default async function Panel() {
const { getUser, getPermission, getOrganization } = getKindeServerSession()
const uzytkownik = await getUser()
if (!uzytkownik) redirect('/api/auth/login')
const organizacja = await getOrganization()
const mozeZarzadzac = await getPermission('zarzadzanie:zespolem')
return <Widok uzytkownik={uzytkownik} organizacja={organizacja} admin={mozeZarzadzac.isGranted} />
}Sprawdzenie uprawnienia po stronie serwera jest tu istotne i warto to podkreślić. Ukrycie przycisku w interfejsie nie jest zabezpieczeniem, bo trasa obsługująca akcję musi sprawdzić to samo.
export async function POST(request: Request) {
const { getPermission, getOrganization } = getKindeServerSession()
const mozeZarzadzac = await getPermission('zarzadzanie:zespolem')
if (!mozeZarzadzac?.isGranted) {
return new Response('Brak uprawnien', { status: 403 })
}
const organizacja = await getOrganization()
await usunCzlonka(await request.json(), organizacja.orgCode)
return new Response(null, { status: 204 })
}Bez tego kroku uprawnienia są kwestią wyglądu, a nie kontroli dostępu. Odczytanie kodu organizacji w tej samej funkcji jest tu równie ważne: bez niego zapytanie usuwające członka nie ma po czym rozpoznać, o którą organizację chodzi, i użytkownik jednej firmy może dotknąć danych innej.
Integracja z Next.js obejmuje zarówno komponenty serwerowe, jak i trasy obsługujące przekierowania. Poza tym dostępne są biblioteki do innych środowisk oraz zwykły przepływ autoryzacyjny, gdy pracujesz w czymś, dla czego gotowej biblioteki nie ma.
Organizacje i wielodostępność
To obszar, w którym decyzje podjęte na starcie są najtrudniejsze do zmiany później, więc warto je przemyśleć.
Pierwsze pytanie brzmi, czy użytkownik może należeć do wielu organizacji. Jeśli tak, aplikacja musi w każdym miejscu wiedzieć, w kontekście której działa, a przełączanie kontekstu jest osobnym przepływem. Jeśli nie, model jest prostszy, ale rozszerzenie go później oznacza migrację danych.
Drugie dotyczy tego, gdzie żyją role. Rola przypisana globalnie użytkownikowi znaczy co innego niż rola przypisana w ramach organizacji. Mieszanie obu prowadzi do sytuacji, w której administrator jednej organizacji ma uprawnienia w innej.
Trzecie to zapraszanie. Przepływ zaproszenia obejmuje wysłanie wiadomości, obsługę odnośnika, przypadek osoby już mającej konto i przypadek zaproszenia wygasłego. Usługa to zapewnia, ale warto sprawdzić, czy jej domyślne zachowanie odpowiada temu, czego oczekujesz.
Warto też pamiętać o wyglądzie. Ekran logowania z domyślnym oznaczeniem usługi jest w porządku przy narzędziu wewnętrznym, a przy produkcie sprzedawanym klientom zwykle wymaga zmiany, co wiąże się z przejściem na plan płatny.
Flagi funkcji w praktyce
Umieszczenie flag w tej samej usłudze co uwierzytelnianie ma zaletę i ograniczenie, które warto znać.
Zaletą jest brak dodatkowego wywołania. Wartość flagi przychodzi w tokenie razem z informacją o użytkowniku i organizacji, więc sprawdzenie kosztuje zero i działa też przy renderowaniu po stronie serwera.
Ograniczeniem jest moment odświeżenia. Flaga zmieniona w panelu zadziała po odświeżeniu tokenu, a nie natychmiast.
const { getFlag } = getKindeServerSession()
const nowyKoszyk = await getFlag('nowy-koszyk', false, 'b')
const limitPozycji = await getFlag('limit-pozycji', 50, 'i')
if (nowyKoszyk.value) return <NowyKoszyk limit={limitPozycji.value} />
return <StaryKoszyk />Drugi argument to wartość zapasowa i warto go podawać zawsze. Flaga usunięta w panelu albo niedostępna z powodu błędu sieci daje wtedy zachowanie domyślne zamiast wyjątku, a przy wyborze wartości zapasowej bezpieczniej jest wskazać wariant stary niż nowy.
Przy stopniowym wypuszczaniu funkcji odstęp odświeżenia jest bez znaczenia, przy wyłączaniu czegoś awaryjnie ma znaczenie i warto wiedzieć, jak długo trwa.
Praktyczne zastosowania są trzy. Wypuszczanie funkcji wybranym klientom przed ogólną dostępnością. Rozróżnianie planów abonamentowych, gdzie flaga odpowiada temu, za co klient zapłacił. Wyłączanie funkcji sprawiającej kłopoty bez wdrażania nowej wersji aplikacji.
Do testów porównawczych z podziałem ruchu i pomiarem wyników to rozwiązanie jest za proste, więc przy takich potrzebach potrzebne będzie osobne narzędzie.
Tokeny i sesje
Warto rozumieć, co dokładnie dostaje aplikacja po zalogowaniu, bo od tego zależy, gdzie sprawdzać uprawnienia i jak długo trwa sesja.
Po zalogowaniu usługa wydaje dwa tokeny. Pierwszy opisuje tożsamość: kto to jest, jaki ma adres pocztowy, jaki obrazek. Drugi służy do wywoływania Twojego interfejsu programistycznego i to w nim siedzą uprawnienia, role i organizacja.
Rozróżnienie ma znaczenie praktyczne. Zaplecze sprawdzające tożsamość na podstawie pierwszego tokenu popełnia błąd, bo ten token nie jest przeznaczony do autoryzacji dostępu do zasobów. Właściwy jest drugi, a jego weryfikacja polega na sprawdzeniu podpisu kluczem publicznym usługi.
import { createRemoteJWKSet, jwtVerify } from 'jose'
const klucze = createRemoteJWKSet(
new URL(`${process.env.KINDE_ISSUER_URL}/.well-known/jwks`)
)
export async function sprawdzToken(token: string) {
const { payload } = await jwtVerify(token, klucze, {
issuer: process.env.KINDE_ISSUER_URL,
audience: process.env.KINDE_AUDIENCE
})
return payload
}Sprawdzenie wystawcy i odbiorcy to dwie linie, których pominięcie unieważnia cały mechanizm. Token podpisany poprawnie, ale wystawiony dla innej aplikacji, przejdzie weryfikację podpisu i zostanie przyjęty, jeśli nie sprawdzisz, dla kogo był przeznaczony.
Drugą sprawą jest czas życia. Token dostępowy wygasa po kilkunastu minutach, a odświeżanie odbywa się w tle. To znaczy, że zmiana uprawnień w panelu zadziała po odświeżeniu, nie natychmiast, i dotyczy to również flag funkcji.
Trzecią jest rozmiar. Wszystkie uprawnienia i flagi lądują w tokenie, więc przy kilkudziesięciu wpisach token rośnie i trafia do każdego żądania. Przy rozbudowanym modelu uprawnień warto sprawdzić, czy nie prościej trzymać w tokenie role, a szczegółowe uprawnienia rozwiązywać po stronie zaplecza.
Ceny
| Plan | Koszt | Co obejmuje |
|---|---|---|
| Free | 0 USD | 10,5 tysiąca aktywnych użytkowników, 5 aktywnych organizacji, 10 flag, 2 role, 1 webhook |
| Pro | 25 USD miesięcznie | 0,0175 USD za użytkownika ponad próg, bez oznaczenia usługi, role i flagi bez limitu, klucze API |
| Plus | 75 USD miesięcznie | 0,0163 USD za użytkownika, zakresy uprawnień, logowanie firmowe bez limitu, 5 środowisk poza produkcją |
| Scale | 250 USD miesięcznie | 0,0151 USD za użytkownika, ustawienia osobne dla każdej organizacji, 10 środowisk poza produkcją |
| Enterprise | wycena indywidualna | Dedykowana infrastruktura, gwarancje dostępności, wsparcie, umowy niestandardowe |
Pierwsza rzecz do zapamiętania: próg 10,5 tysiąca aktywnych użytkowników obowiązuje na każdym planie, a nie tylko na darmowym. Płatny plan nie kupuje większej puli, tylko zdejmuje limity funkcji i obniża stawkę za nadwyżkę.
Druga: stawka za użytkownika ponad próg jest inna na każdym planie i wynosi 0,0175 USD na Pro, 0,0163 USD na Plus oraz 0,0151 USD na Scale. Przy dwudziestu tysiącach aktywnych użytkowników na planie Pro nadwyżka to dziewięć i pół tysiąca osób, czyli około stu sześćdziesięciu sześciu dolarów, a razem z abonamentem około stu dziewięćdziesięciu dolarów miesięcznie.
Przekroczenie progu niczego nie blokuje. Nadwyżka dolicza się automatycznie po opublikowanej stawce, więc rachunek rośnie płynnie, zamiast zatrzymywać logowanie. Osobno rozliczane są aktywne organizacje: pięć w planie darmowym, pięćdziesiąt w płatnych, a każda kolejna kosztuje od 0,43 do 0,50 USD zależnie od planu. Organizacja z jednym aktywnym użytkownikiem nie jest liczona.
Wyższy próg darmowy jest tu głównym argumentem wobec konkurencji i warto rozumieć, co za nim stoi. Usługa nie zamyka mechanizmów bezpieczeństwa za progami cenowymi, więc logowanie bez hasła, drugi składnik w aplikacji uwierzytelniającej i połączenia firmowe działają już na planie darmowym. Płacisz za skalę i za usunięcie oznaczenia, a nie za odblokowanie zabezpieczeń.
Ograniczone są natomiast liczby, i to one decydują o tym, kiedy trzeba przejść wyżej. Plan darmowy daje dwie role z dziesięcioma uprawnieniami, dziesięć flag funkcji, jeden webhook, jedno połączenie firmowe i pięć aktywnych organizacji. Klucze API oraz zakresy uprawnień są dostępne dopiero na planach płatnych.
Przy szacowaniu kosztu policz aktywnych użytkowników, a nie założone konta. Aplikacja z pięćdziesięcioma tysiącami kont, z których loguje się pięć tysięcy miesięcznie, mieści się w progu darmowym. Warto natomiast sprawdzić, jak dostawca liczy aktywność, bo definicje bywają różne i wpływają na rachunek bardziej niż sama stawka.
Kinde kontra alternatywy
| Rozwiązanie | Mocna strona | Słabość | Kiedy wybrać |
|---|---|---|---|
| Kinde | Organizacje i flagi w komplecie, wysoki próg darmowy | Mniejszy ekosystem, mniej materiałów | Produkt dla firm z zespołami i planami abonamentowymi |
| Clerk | Gotowe komponenty interfejsu, dopracowane wrażenia | Koszt przy dużej skali | Aplikacja, w której liczy się czas do wdrożenia |
| Auth0 | Dojrzałość, zgodność, rozbudowane możliwości | Złożoność i cena | Duża organizacja z wymogami zgodności |
| Supabase | Uwierzytelnianie razem z bazą | Mniej rozbudowane role i organizacje | Projekt już na tej platformie |
Wybór między pierwszymi dwoma wierszami zależy od tego, czy potrzebujesz organizacji. Przy aplikacji dla użytkowników indywidualnych gotowe komponenty konkurenta oszczędzają więcej czasu. Przy produkcie sprzedawanym firmom, gdzie klient zaprasza zespół i ma role, komplet w jednej usłudze wygrywa.
Ostatni wiersz warto rozważyć, gdy projekt i tak stoi na tej platformie. Uwierzytelnianie razem z bazą upraszcza architekturę, choć przy rozbudowanych rolach i wielu organizacjach prędzej czy później dojdziesz do własnej warstwy uprawnień.
Warto też uczciwie powiedzieć, że własne uwierzytelnianie jest wykonalne i przy prostych wymaganiach niedrogie. Logowanie hasłem z porządnym haszowaniem i sesją w ciasteczku to dzień pracy. Koszt pojawia się przy tym, co idzie potem: resetowanie hasła, drugi składnik, logowanie przez zewnętrznych dostawców, klucze dostępu, blokowanie po nieudanych próbach i obsługa przejęć kont. Usługa zewnętrzna kupuje właśnie te rzeczy, a nie samo logowanie.
Granica przebiega tam, gdzie zaczynają się wymagania zgodności albo klienci firmowi. Wtedy własna implementacja oznacza audyt i dokumentację, których nikt nie planował, a gotowa usługa dostarcza je razem z produktem.
Co warto ustalić przed wdrożeniem
Uwierzytelnianie należy do rzeczy, których wymiana po roku jest kosztowna, więc kilka decyzji warto podjąć świadomie na starcie.
Pierwsza dotyczy identyfikatora użytkownika. W Twojej bazie użytkownik ma własny wiersz, a usługa wydaje mu swój identyfikator. Powiązanie tych dwóch rzeczy przez identyfikator usługi jest wygodne i wiąże Cię z dostawcą. Trzymanie własnego identyfikatora, do którego identyfikator usługi jest tylko odnośnikiem, kosztuje jedną kolumnę i zostawia drogę wyjścia.
Druga to zakres danych trzymanych po stronie usługi. Adres pocztowy i nazwa muszą tam być, bo bez nich logowanie nie działa. Wszystko poza tym, w tym preferencje, historia i dane rozliczeniowe, lepiej żeby zostało w Twojej bazie, gdzie masz nad tym kontrolę i możesz to przeszukiwać.
Trzecia to obsługa zdarzeń. Usługa potrafi powiadomić Twoje zaplecze o rejestracji, zmianie danych albo usunięciu konta. Bez tego Twoja baza rozjeżdża się z usługą przy każdej zmianie dokonanej w panelu, a rozjazd zauważa się zwykle przy pierwszym raporcie.
Czwarta to środowiska. Jedno środowisko dla produkcji i testów oznacza, że dane testowe mieszają się z prawdziwymi, a każdy eksperyment z konfiguracją dotyka klientów. Rozdzielenie ich nie wymaga tu planu płatnego: konto darmowe dostaje jedno środowisko produkcyjne i jedno poza produkcją, i tyle samo daje plan Pro. Dopiero trzecie środowisko kosztuje osobno, po pięć dolarów miesięcznie na Pro, a plany wyższe mieszczą w abonamencie odpowiednio pięć i dziesięć środowisk poza produkcją. Jeśli więc planujesz osobne środowisko dla testów, dla podglądu i dla szkoleń, policz je zawczasu, bo to one, a nie liczba użytkowników, wypychają rachunek w górę.
Typowe błędy
Pierwszy to sprawdzanie uprawnień wyłącznie w interfejsie. Ukryty przycisk nie chroni trasy, która wykonuje akcję, więc sprawdzenie musi być po stronie serwera.
Drugi to mieszanie ról globalnych z rolami w organizacji. Prowadzi to do sytuacji, w której administrator jednej organizacji ma dostęp do danych innej, a błąd wychodzi po wdrożeniu.
Trzeci to zakładanie natychmiastowej zmiany flag. Wartość odświeża się razem z tokenem, więc wyłączenie funkcji awaryjnie działa z opóźnieniem i trzeba to uwzględnić w planie na wypadek incydentu.
Czwarty to szacowanie kosztu po liczbie kont. Rozliczenie idzie za aktywnych użytkowników miesięcznie, co przy aplikacjach z długim ogonem kont rzadko używanych daje zupełnie inny wynik.
Piąty to przenoszenie użytkowników bez planu. Migracja z innej usługi wymaga przeniesienia haseł, a te są zaszyfrowane, więc trzeba sprawdzić, czy format jest zgodny, zanim zaplanujesz termin.
Szósty to poleganie na tej usłudze przy testach porównawczych z podziałem ruchu. Flagi nadają się do wypuszczania funkcji, a nie do pomiaru wpływu na wskaźniki, i do tego drugiego potrzebne jest inne narzędzie.
FAQ
Ile kosztuje Kinde?
Plan darmowy obejmuje do dziesięciu i pół tysiąca aktywnych użytkowników miesięcznie ze wszystkimi podstawowymi funkcjami. Ten sam próg obowiązuje na planach płatnych, które kosztują dwadzieścia pięć, siedemdziesiąt pięć i dwieście pięćdziesiąt dolarów miesięcznie. Powyżej progu dochodzi stawka za użytkownika, malejąca wraz z planem: 0,0175 USD na Pro, 0,0163 USD na Plus i 0,0151 USD na Scale.
Czym różni się od Clerka?
Clerk daje gotowe komponenty interfejsu i dopracowane wrażenia z logowania, więc wdrożenie zajmuje mniej czasu. Kinde daje w komplecie organizacje, role i flagi funkcji, co przy produkcie sprzedawanym firmom oszczędza dokładania osobnych narzędzi.
Czy flagi funkcji zastępują osobne narzędzie?
Do wypuszczania funkcji wybranym klientom i do rozróżniania planów abonamentowych tak. Do testów porównawczych z podziałem ruchu i pomiarem wskaźników nie, bo to rozwiązanie jest prostsze i nie ma warstwy analitycznej.
Czy obsługuje logowanie firmowe?
Tak, i to bez wchodzenia na plan płatny: jedno połączenie z dostawcą tożsamości klienta mieści się już w planie darmowym, podobnie jak własne połączenie SAML. Dopiero drugi taki klient wymaga planu Plus albo Scale, gdzie liczba połączeń jest nieograniczona bez dopłat. To zwykle wymóg przy sprzedaży do większych organizacji i warto sprawdzić szczegóły konfiguracji, zanim obiecasz termin klientowi.
Czy da się przenieść użytkowników z innej usługi?
Tak, przy czym kluczowe jest przeniesienie haseł. Są zaszyfrowane, więc import działa tylko przy zgodnym formacie, a w przeciwnym razie użytkownicy muszą ustawić hasło ponownie. To trzeba sprawdzić przed zaplanowaniem migracji, bo wpływa na komunikat do klientów.
Dokumentacja stoi na stronie projektu, a aktualne progi cenowe na stronie cennika.