Architecture & Delivery
SupabaseJWTAuthenticationProduct ArchitectureRisk Patterns

Jak duży JSON w Supabase user_metadata może zepsuć aplikację

Produkty rzadko upadają przez jedną katastrofalną decyzję. Częściej przez ciąg „niewinnych” skrótów, które rosną po cichu, aż coś pęka.

`user_metadata` w Supabase to taka pułapka: przydatne na początku, niebezpieczne w skali i zwodniczo łatwe do nadużycia.

Zespoły traktują je jak luźny schowek na dane użytkownika. Przecież to tylko JSON? Tak, ale z konsekwencją: Supabase umieszcza metadata w JWT sesji. W opisywanym wariancie z cookies token podróżuje z żądaniami. Więcej metadata oznacza większe żądania.

To nie wzorzec przechowywania. To wzorzec obciążenia przesyłanego przez system. Z konsekwencjami architektonicznymi.

Meme about guys sitting still and then cheering

Mechanizm, który umyka

Ścieżka wygląda tak:

1. Zapisujesz dane w `auth.users.user_metadata`.

2. Supabase odwzorowuje metadata w JWT.

3. JWT trafia do cookies.

4. Cookies podróżują z żądaniami.

5. Cały pipeline wozi dane osobowe, których nigdy nie potrzebował.

Działa, dopóki nie przestanie.

Kilka pól wygląda niewinnie. Dodaj zachowania, stan UI, preferencje katalogów i analizę profilu. Żądania rosną, nagłówki puchną, debugowanie robi się niespójne, a uwierzytelnianie przypomina sygnalizator ze zwarciem.

W końcu coś pęka głośno. Typowe objawy:

•Aplikacja wylogowuje bez ostrzeżenia.
•Przeglądarki odrzucają żądania.
•Serwer zwraca HTTP 431: Request Header Fields Too Large.

Nieważne, jak czysty masz kod. Warstwa uwierzytelniania stała się wąskim gardłem.

Kiedy trafiłem na tę ścianę

To nie teoria. Sam w nią uderzyłem.

Przez dwa pełne weekendy szukałem przyczyny niestabilnego logowania. Bez dużych wdrożeń i skomplikowanych premier. Kilka dopisków do `user_metadata`: linia tutaj, stan UI tam.

Nic, co wyglądało groźnie. Wszystko, co groźne było.

Nie baza. Nie infrastruktura. Nawet nie wydajność w tradycyjnym sensie. JWT.

Token miał być kluczem, a został walizką JSON-u ciągniętą z każdym żądaniem. Nie przez megabajty danych, tylko kilkadziesiąt linii metadata, które niepostrzeżenie przekroczyły granice rozsądku.

Nie widowiskowe włamanie. Powolne duszenie.

Zasada, której nikt nie uczy

Sesja ≠ magazyn

JWT nie jest magazynem, cache’em ani kontenerem na zmienny kontekst produktu.

Token powinien być mały, przewidywalny, stabilny i nudny. Reszta należy gdzie indziej.

Wiedzieć, kim jest użytkownik? Dobrze. Nosić preferencje, analitykę, stan UI, ostatnie działania i połowę roadmapy? Pakujesz produkt do paszportu. A paszport nie służy do przewozu mebli.

Właściwy wzorzec

W `user_metadata` trzymaj to, co zmieści się na wizytówce. Resztę w dedykowanych tabelach.

Moja zasada: kontekst tożsamości do `user_metadata`, reszta do własnych tabel. Zmienia się z czasem? Nie wkładaj do sesji. Wygodne? Zadaj pytanie. Nie wiesz? Oddziel.

Szerszy obraz

Nie chodzi wyłącznie o Supabase. Chodzi o różnicę między produktem, który się skaluje, a takim, który kumuluje entropię.

Małe błędy wychodzą nie od razu, lecz gdy produkt łapie trakcję. Najgorszy moment na niespodzianki.

Sesja już waży za dużo? Logi logowania są zagadką? Metadata robi więcej niż baza? Stoisz na początku awarii, której można uniknąć. Dobra wiadomość: da się to naprawić.

Wniosek

Udane produkty nie toną we własnych danych. Nadają im strukturę.

Uwierzytelnianie ma być uściskiem dłoni, nie transportem towarów. Jeśli JWT nosi metadata zamiast tożsamości, nie skalujesz. Stoisz. Możesz to poprawić, zanim zrobi się drogo.

Porozmawiajmy o jasności.

Mniej gadania — więcej zysku. Zbudujmy prawdziwy system!

Bezpośrednia inżynieria na poziomie kodu dla operacji, które nie mogą sobie pozwolić na awarie albo agencyjne opóźnienia