[{"data":1,"prerenderedAt":381},["ShallowReactive",2],{"docs:doc:\u002Fpl\u002Fdocs\u002Fprzewodniki\u002Farchitektura":3,"docs:pages:docs_pl":310},{"id":4,"title":5,"alt":6,"body":7,"description":299,"extension":300,"key":301,"meta":302,"navigation":303,"order":304,"path":305,"placeholder":306,"seo":307,"stem":308,"__hash__":309},"docs_pl\u002Fpl\u002Fdocs\u002Fprzewodniki\u002Farchitektura.md","Jak zbudowana jest Kleora","\u002Fen\u002Fdocs\u002Fguides\u002Farchitecture",{"type":8,"value":9,"toc":287},"minimark",[10,22,27,39,46,53,57,123,134,141,145,152,159,166,170,214,217,220,224,250,254,274,277,281,284],[11,12,15,19],"callout",{"title":13,"type":14},"Hostowania u siebie dzisiaj nie wspieramy","warning",[16,17,18],"p",{},"Nie ma opublikowanego obrazu, wspieranej konfiguracji ani instrukcji wdrożenia,\nbo nie ma za nimi niczego: opisane niżej elementy działają jako jeden artefakt\nwdrożeniowy, a granica, która pozwoliłaby rozstawić je samodzielnie, jeszcze nie\nistnieje. Jeśli szukasz tu instrukcji uruchomienia usługi Kleora na własnej\ninfrastrukturze, uczciwa odpowiedź brzmi: nie da się — i wolimy powiedzieć to\ntutaj, niż pozwolić Ci dowiedzieć się tego po trzech godzinach.",[16,20,21],{},"Dalej opisana jest architektura usługi hostowanej — zgodna z prawdą i przydatna,\nkiedy trzeba rozumować o opóźnieniach, awariach i o tym, gdzie leżą dane Twoich\nużytkowników.",[23,24,26],"h2",{"id":25},"jeden-adres-na-środowisko","Jeden adres na środowisko",[16,28,29,30,34,35,38],{},"Każde środowisko każdej aplikacji ma własny host issuera:\n",[31,32,33],"code",{},"https:\u002F\u002Facme.kleora.eu"," dla produkcji i\n",[31,36,37],{},"https:\u002F\u002Facme.sandbox.kleora.eu"," dla sandboksa. To nie jest kosmetyka.\nIssuer w OpenID Connect jest identyfikowany adresem URL, więc danie każdemu\nśrodowisku własnego oznacza, że discovery, zestawy kluczy, tokeny i sesje\nrozdziela sam protokół, a nie sprawdzenie gdzieś w naszym kodzie.",[16,40,41,42,45],{},"Żądanie przychodzące na taki host zostaje przypisane do dokładnie jednego\nśrodowiska, zanim cokolwiek zostanie wyrutowane. Nieznany host to ",[31,43,44],{},"404",", nigdy\nodesłanie gdzie indziej.",[16,47,48,49,52],{},"API zarządzania odpowiada na innym hoście — ",[31,50,51],{},"api.kleora.io"," — i tylko tam.",[23,54,56],{"id":55},"dwie-powierzchnie-i-to-czym-każda-z-nich-może-być","Dwie powierzchnie i to, czym każda z nich może być",[58,59,60,76],"table",{},[61,62,63],"thead",{},[64,65,66,70,73],"tr",{},[67,68,69],"th",{},"Powierzchnia",[67,71,72],{},"Gdzie odpowiada",[67,74,75],{},"Kto może ją wołać",[77,78,79,98,109],"tbody",{},[64,80,81,85,95],{},[82,83,84],"td",{},"OAuth 2.1 \u002F OpenID Connect",[82,86,87,90,91,94],{},[31,88,89],{},"\u002Foauth\u002F",", ",[31,92,93],{},"\u002F.well-known\u002F"," na hoście issuera",[82,96,97],{},"Każdy. To powierzchnia, która wydaje dane uwierzytelniające.",[64,99,100,103,106],{},[82,101,102],{},"Hostowane strony logowania",[82,104,105],{},"cała reszta na hoście issuera",[82,107,108],{},"Twoi użytkownicy, w przeglądarce.",[64,110,111,114,120],{},[82,112,113],{},"API zarządzania",[82,115,116,119],{},[31,117,118],{},"\u002Fapi\u002Fv1\u002F"," na hoście zarządzania",[82,121,122],{},"Uwierzytelnieni, w zasięgu jednego środowiska albo konta.",[16,124,125,126,130,131,133],{},"Podział wymusza host, na który przyszło żądanie: API zarządzania ",[127,128,129],"strong",{},"nie istnieje","\nna hoście issuera, a powierzchnia OAuth nie istnieje na hoście zarządzania. Nie\n„jest odrzucane” — trasy nie są tam w ogóle zamontowane, więc odpowiedzią jest\n",[31,132,44],{}," z konstrukcji. W kodzie obie mieszkają też w osobnych pakietach, więc\npytanie „czy to jest osiągalne bez danych uwierzytelniających?” zawsze ma\nodpowiedź celową, a nie przypadkową.",[16,135,136,137,140],{},"Przed obiema stoi serwer brzegowy. Dla hosta issuera decyduje po ścieżce:\nendpointy OAuth i przepływu idą do aplikacji, a cała reszta serwowana jest z\npaczki stron logowania. Nagłówek ",[31,138,139],{},"Host"," przekazuje nietknięty — i to właśnie\npozwala jednemu wdrożeniu odpowiadać na issuery wszystkich klientów bez ich\nlisty gdziekolwiek.",[23,142,144],{"id":143},"strony-logowania-to-statyczna-aplikacja","Strony logowania to statyczna aplikacja",[16,146,147,148,151],{},"Strony, które widzą Twoi użytkownicy — logowanie, rejestracja, potwierdzenie\nadresu, reset hasła, wybór przestrzeni roboczej — to statyczna aplikacja\njednostronicowa serwowana na hoście issuera Twojej aplikacji. Rozmawia wyłącznie\nz ",[31,149,150],{},"\u002Fflow\u002F*"," w tym samym origin, a to jest API w JSON; serwer nie renderuje\nżadnego HTML-a.",[16,153,154,155,158],{},"Dwie konsekwencje warte zapamiętania. Twój branding jest ",[127,156,157],{},"danymi",", nie\nszablonem: strona pobiera rekord brandingu jako JSON i go stosuje, dlatego zmiana\nkoloru działa bez wdrożenia po którejkolwiek ze stron. I logowanie wymaga\nJavaScriptu.",[16,160,161,162,165],{},"Zakończenie przepływu to zawsze nawigacja najwyższego poziomu z powrotem do\n",[31,163,164],{},"\u002Foauth\u002Fauthorize\u002Fcontinue",", więc kod autoryzacyjny trafia wyłącznie do\nodpowiedzi nawigacyjnej — nigdy do treści JSON, którą mógłby odczytać skrypt.",[23,167,169],{"id":168},"gdzie-leży-stan","Gdzie leży stan",[58,171,172,182],{},[61,173,174],{},[64,175,176,179],{},[67,177,178],{},"Magazyn",[67,180,181],{},"Co trzyma",[77,183,184,194,204],{},[64,185,186,191],{},[82,187,188],{},[127,189,190],{},"PostgreSQL",[82,192,193],{},"Źródło prawdy. Konta, aplikacje, środowiska, użytkownicy, przestrzenie robocze, członkostwa, role, klienci, klucze i dziennik zdarzeń.",[64,195,196,201],{},[82,197,198],{},[127,199,200],{},"Redis",[82,202,203],{},"Cache, liczniki limitów zapytań i wyniki zadań w tle — wszystko, co da się odtworzyć albo czemu wolno wygasnąć.",[64,205,206,211],{},[82,207,208],{},[127,209,210],{},"RabbitMQ",[82,212,213],{},"Kolejka pracy, która nie może zginąć między zleceniem a wykonaniem: przede wszystkim wysyłka e-maili.",[16,215,216],{},"Każdy wiersz należący do środowiska niesie tożsamość tego środowiska, a dostęp do\ndanych jest z konstrukcji ograniczony do jednego środowiska — zapytanie bez\nśrodowiska to błąd programisty, który kończy się wyjątkiem, a nie cudzymi\nwierszami.",[16,218,219],{},"Tokeny dostępu są bezstanowe: to podpisane JWT i weryfikacja nie zagląda\nnigdzie. Tokeny odświeżania, sesje i kody autoryzacyjne są odwrotnością — to\nwiersze w PostgreSQL, więc dla nich unieważnienie działa natychmiast.",[23,221,223],{"id":222},"co-to-znaczy-dla-twojej-aplikacji","Co to znaczy dla Twojej aplikacji",[225,226,227,234,244],"ul",{},[228,229,230,233],"li",{},[127,231,232],{},"Weryfikacja nie kosztuje Cię żadnego żądania do nas."," Twoje API pobiera\nzestaw kluczy raz, trzyma go tak długo, jak mówi odpowiedź, i sprawdza podpisy\nlokalnie. Role i uprawnienia są w tokenie.",[228,235,236,239,240,243],{},[127,237,238],{},"Rotacja klucza nie wymaga skoordynowanego wdrożenia."," Kolejny klucz\npodpisujący trafia do zestawu, zanim zostanie użyty, więc ",[31,241,242],{},"kid"," świeżo\npodpisanego tokenu jest już w Twoim cache'u.",[228,245,246,249],{},[127,247,248],{},"Obie powierzchnie nie są jeszcze od siebie odizolowane."," Dziś to jeden\nartefakt wdrożeniowy, więc nie da się ich skalować ani ograniczać niezależnie.\nGranica w kodzie jest prawdziwa, granica wdrożeniowa to praca na przyszłość — i\nwolimy to powiedzieć, niż sugerować izolację, której nie dostajesz.",[23,251,253],{"id":252},"kontrakty-na-których-możesz-budować","Kontrakty, na których możesz budować",[225,255,256,262,268],{},[228,257,258,261],{},[31,259,260],{},"{issuer}\u002F.well-known\u002Fopenid-configuration"," — discovery, a z niego zestaw\nkluczy. Wszystko, czego potrzebuje dowolny klient OpenID Connect; nasze SDK są\nudogodnieniem, nie wymogiem.",[228,263,264,267],{},[31,265,266],{},"{issuer}\u002Foauth\u002Fopenapi.json"," — dokument OpenAPI powierzchni OAuth.",[228,269,270,273],{},[31,271,272],{},"https:\u002F\u002Fapi.kleora.io\u002Fapi\u002Fv1\u002Fopenapi.json"," — to samo dla API\nzarządzania, i dokument, z którego generowane są nasze własne klienty.",[16,275,276],{},"Przepływem przeglądarkowym jest authorization code z PKCE; implicit i password\ngrant nie są oferowane.",[23,278,280],{"id":279},"dlaczego-nie-ma-opowieści-o-hostowaniu-u-siebie","Dlaczego nie ma opowieści o hostowaniu u siebie",[16,282,283],{},"Musiałyby być spełnione trzy rzeczy i nie jest spełniona żadna. Nie ma granicy\nwdrożeniowej między dwiema powierzchniami API, więc „uruchom publiczną połowę w\nswojej strefie DMZ” nie jest konfiguracją — jest zmianą architektury. Nie ma\nopublikowanych obrazów ani niczego wersjonowanego do uruchomienia. I nie ma\nwspieranej konfiguracji: istniejące ustawienia zakładają nasz własny kontekst\noperacyjny, a my nigdy nie uruchamialiśmy tego nigdzie indziej.",[16,285,286],{},"Wolimy opublikować tę stronę niż instrukcję wdrożenia, która po cichu nie działa.\nJeśli to się zmieni, stanie się tak dlatego, że będzie co uruchamiać — i wtedy\npowie to właśnie ta strona.",{"title":288,"searchDepth":289,"depth":289,"links":290},"",3,[291,293,294,295,296,297,298],{"id":25,"depth":292,"text":26},2,{"id":55,"depth":292,"text":56},{"id":143,"depth":292,"text":144},{"id":168,"depth":292,"text":169},{"id":222,"depth":292,"text":223},{"id":252,"depth":292,"text":253},{"id":279,"depth":292,"text":280},"Kształt usługi hostowanej — jeden adres na środowisko, dwie powierzchnie API i miejsce, w którym leży stan. Oraz dlaczego hostowania u siebie dzisiaj nie wspieramy.","md","guides\u002Farchitecture",{},true,30,"\u002Fpl\u002Fdocs\u002Fprzewodniki\u002Farchitektura",false,{"title":5,"description":299},"pl\u002Fdocs\u002Fprzewodniki\u002Farchitektura","huH4HTZgrCYoLjVNpfjYXgMzn1DvP-VKlvDinXnNfWI",[311,317,323,329,334,335,341,346,351,356,361,366,371,376],{"path":312,"title":313,"description":314,"order":315,"key":316},"\u002Fpl\u002Fdocs","Dokumentacja Kleora","Dodaj hostowane logowanie do swojej aplikacji, sprawdź token w swoim API i zarządzaj użytkownikami, przestrzeniami roboczymi i rolami z jednej konsoli.",0,"index",{"path":318,"title":319,"description":320,"order":321,"key":322},"\u002Fpl\u002Fdocs\u002Fpierwsze-kroki","Pierwsze kroki","Od pustego projektu do działającego logowania — i paczki, które do tego prowadzą.",10,"getting-started\u002Findex",{"path":324,"title":325,"description":326,"order":327,"key":328},"\u002Fpl\u002Fdocs\u002Fpierwsze-kroki\u002Finstalacja","Instalacja SDK","Pięć paczek, które publikujemy, do czego służy każda z nich i jakiej konfiguracji wymaga.",20,"getting-started\u002Finstallation",{"path":330,"title":331,"description":332,"order":321,"key":333},"\u002Fpl\u002Fdocs\u002Fpierwsze-kroki\u002Fszybki-start","Szybki start","Załóż aplikację, podłącz SDK przeglądarkowe i zaloguj się po raz pierwszy — w całości w sandboksie.","getting-started\u002Fquickstart",{"path":305,"title":5,"description":299,"order":304,"key":301},{"path":336,"title":337,"description":338,"order":339,"key":340},"\u002Fpl\u002Fdocs\u002Fprzewodniki\u002Fframeworki\u002Fexpress","Express","Sprawdzanie tokenu dostępu we własnym API — middleware, uprawnienia i trzy odpowiedzi, jakie może mieć odmowa.",40,"guides\u002Fquickstarts\u002Fexpress",{"path":342,"title":343,"description":344,"order":321,"key":345},"\u002Fpl\u002Fdocs\u002Fprzewodniki\u002Fframeworki","Szybki start dla frameworków","Po jednej stronie na stos — Next.js, Nuxt, Express i zwykła przeglądarka — i dwa adresy powrotne, które łączą je wszystkie.","guides\u002Fquickstarts\u002Findex",{"path":347,"title":348,"description":349,"order":327,"key":350},"\u002Fpl\u002Fdocs\u002Fprzewodniki\u002Fframeworki\u002Fnextjs","Next.js","SDK przeglądarkowe w aplikacji na App Router — leniwy klient, trasa powrotna i sprawdzanie tokenu w route handlerze.","guides\u002Fquickstarts\u002Fnextjs",{"path":352,"title":353,"description":354,"order":304,"key":355},"\u002Fpl\u002Fdocs\u002Fprzewodniki\u002Fframeworki\u002Fnuxt","Nuxt","Moduł dla Nuxt — dwie linijki konfiguracji, strona powrotu, której nie piszesz, i middleware chroniący stronę z jej własnych metadanych.","guides\u002Fquickstarts\u002Fnuxt",{"path":357,"title":358,"description":359,"order":321,"key":360},"\u002Fpl\u002Fdocs\u002Fprzewodniki\u002Fframeworki\u002Fprzegladarka","Zwykła przeglądarka","Jedna instancja klienta, jedna trasa powrotna i token dostępu do każdego żądania, które wysyła Twoja aplikacja.","guides\u002Fquickstarts\u002Fbrowser",{"path":362,"title":363,"description":364,"order":327,"key":365},"\u002Fpl\u002Fdocs\u002Fprzewodniki","Przewodniki","Jak podłączyć usługę Kleora do swojego stosu, jakich słów używa produkt i jak zbudowana jest usługa hostowana.","guides\u002Findex",{"path":367,"title":368,"description":369,"order":327,"key":370},"\u002Fpl\u002Fdocs\u002Fprzewodniki\u002Fpojecia","Przestrzenie robocze, role i środowiska","Pięć słów, z których zbudowany jest produkt, to, które z nich niosą Twoje tokeny, i jak zmiana roli dociera do działającej aplikacji.","guides\u002Fconcepts",{"path":372,"title":373,"description":374,"order":304,"key":375},"\u002Fpl\u002Fdocs\u002Freferencje","Referencje","Materiały referencyjne dla API HTTP i paczek SDK.","reference\u002Findex",{"path":377,"title":378,"description":379,"order":321,"key":380},"\u002Fpl\u002Fdocs\u002Freferencje\u002Fpodswietlanie","Podświetlanie kodu","Po jednym bloku na każdą wstępnie wczytaną gramatykę Shiki — próbka, nie strona referencyjna.","reference\u002Fcode-highlighting",1790698198026]