Uwierzytelnianie: użycie JWT a sesja


122

Jaka jest zaleta używania tokenów JWT nad sesjami w sytuacjach takich jak uwierzytelnianie?

Czy jest używane jako samodzielne podejście, czy jest używane w sesji?

Odpowiedzi:


213

JWT nie ma korzyści z używania „sesji” na jedno słowo. Tokeny JWT zapewniają środki do utrzymywania stanu sesji na kliencie zamiast wykonywania tego na serwerze.

Pytając o to, ludzie często mają na myśli „Jakie są zalety używania tokena JWT w porównaniu z sesjami po stronie serwera

W przypadku sesji po stronie serwera będziesz musiał albo przechowywać identyfikator sesji w bazie danych, albo zachować go w pamięci i upewnić się, że klient zawsze trafia na ten sam serwer. Oba mają wady. W przypadku bazy danych (lub innego scentralizowanego magazynu) staje się to wąskim gardłem i rzeczą do utrzymania - w zasadzie dodatkowe zapytanie do wykonania przy każdym żądaniu.

Dzięki rozwiązaniu w pamięci ograniczasz skalowanie poziome, a na sesje będą miały wpływ problemy z siecią (klienci korzystający z roamingu między Wi-Fi a mobilnymi danymi, ponowne uruchamianie serwerów itp.)

Przeniesienie sesji do klienta oznacza usunięcie zależności od sesji po stronie serwera, ale narzuca własny zestaw wyzwań.

  • Bezpieczne przechowywanie tokena
  • bezpieczne transportowanie
  • Sesje tokenów JWT mogą być czasami trudne do unieważnienia.
  • Ufanie roszczeniom klienta.

Te problemy są wspólne dla tokena JWT i innych mechanizmów sesji po stronie klienta.

JWT w szczególności zajmuje się ostatnią z nich. Warto zrozumieć, czym jest token JWT:

To trochę informacji. W przypadku sesji użytkowników możesz podać nazwę użytkownika i czas wygaśnięcia tokenu. Ale może to być wszystko, nawet identyfikator sesji lub cały profil użytkownika. (Nie rób tego jednak) Posiada bezpieczny podpis, który zapobiega generowaniu fałszywych tokenów przez złośliwe strony (potrzebujesz dostępu do klucza prywatnego serwera, aby je podpisać i możesz sprawdzić, czy nie zostały zmodyfikowane po podpisaniu) wysyłaj je z każdym żądaniem, tak jak Authorizationwysyłany byłby plik cookie lub nagłówek. W rzeczywistości są one często wysyłane w Authorizationnagłówku HTTP, ale użycie plików cookie też jest w porządku.

Token jest podpisany, więc serwer może zweryfikować jego pochodzenie. Zakładamy, że serwer ufa swojej własnej zdolności do bezpiecznego podpisywania (powinieneś użyć standardowej biblioteki: nie próbuj robić tego samodzielnie i odpowiednio zabezpiecz serwer)

W kwestii bezpiecznego transportu tokena często odpowiedzią jest przesłanie go zaszyfrowanym kanałem, zwykle przez httpS.

Jeśli chodzi o bezpieczne przechowywanie tokena w kliencie, musisz upewnić się, że złoczyńcy nie mogą się do niego dostać. Oznacza to (głównie) uniemożliwienie JS ze złych stron internetowych odczytania tokenu w celu wysłania go z powrotem. Jest to łagodzone przy użyciu tych samych strategii, które są używane do łagodzenia innych rodzajów ataków XSS.

Jeśli chcesz unieważnić tokeny JWT, z pewnością można to osiągnąć. Przechowywanie epoki na użytkownika tylko dla użytkowników, którzy zażądali zakończenia swoich „innych sesji” jest bardzo wydajną metodą, która prawdopodobnie będzie wystarczająco dobra. Jeśli aplikacja wymaga unieważnienia na sesję, wówczas identyfikator sesji można zachować w ten sam sposób, a tabela „zabitych tokenów” może być nadal znacznie mniejsza niż pełna tabela użytkowników (wystarczy zachować rekordy nowsze niż najdłuższy dozwolony okres istnienia tokenu). Tak więc możliwość unieważnienia tokena częściowo neguje korzyści z sesji po stronie klienta, ponieważ musiałbyś utrzymywać stan zabitej sesji. Najprawdopodobniej będzie to znacznie mniejsza tabela niż oryginalna tabela stanu sesji, więc wyszukiwania są nadal bardziej wydajne.

Inną korzyścią płynącą z używania tokenów JWT jest to, że można je stosunkowo łatwo wdrożyć przy użyciu bibliotek dostępnych w prawdopodobnie każdym języku, jakiego można się spodziewać. Jest również całkowicie niezależny od początkowego schematu uwierzytelniania użytkownika - jeśli przejdziesz na system oparty na odciskach palców, nie musisz wprowadzać żadnych zmian w schemacie zarządzania sesjami.

Bardziej subtelna korzyść: Ponieważ JWT może przenosić „informacje”, a klient ma do nich dostęp, możesz teraz zacząć robić sprytne rzeczy. Na przykład przypomnij użytkownikowi, że jego sesja wygaśnie na kilka dni przed wylogowaniem, dając mu możliwość ponownego uwierzytelnienia na podstawie daty wygaśnięcia tokena. Cokolwiek możesz sobie wyobrazić.

Krótko mówiąc: tokeny JWT odpowiadają na niektóre pytania i wady innych technik sesji.

  1. „Tańsze” uwierzytelnianie, ponieważ można wyeliminować obieg bazy danych w obie strony (lub przynajmniej mieć znacznie mniejszą tabelę do przeszukiwania!), Co z kolei umożliwia skalowanie w poziomie.
  2. Twierdzenia po stronie klienta odporne na manipulacje.

Chociaż tokeny JWT nie odpowiadają na inne kwestie, takie jak bezpieczne przechowywanie lub transport, nie wprowadzają żadnych nowych problemów dotyczących bezpieczeństwa.

Wokół tokena JWT istnieje wiele negatywnych opinii, ale jeśli zastosujesz takie same zabezpieczenia, jak w przypadku innych typów uwierzytelniania, nic ci nie będzie.

Ostatnia uwaga: nie chodzi również o pliki cookie kontra tokeny. Pliki cookie to mechanizm służący do przechowywania i transportu bitów informacji i mogą być również wykorzystywane do przechowywania i transportu tokenów JWT.


4
Warto zauważyć, że sesje po stronie serwera również nie muszą przechowywać żadnych informacji na serwerze. Serwer może używać klienta jako magazynu w taki sam sposób, jak robi to JWT. Prawdziwa różnica polega na 1) unikaniu reguł bezpieczeństwa przeglądarki przez przekazywanie wartości jako nagłówka żądania innego niż nagłówek pliku cookie oraz 2) na znormalizowanym formacie z JWT.
Xeoncross

1
Czy powiedziałbyś, że przechowywanie pliku jwt w lokalnym magazynie jest bezpieczne? Jeśli nie, gdzie jest bezpieczne miejsce do zapisania go, aby użytkownik był zalogowany?
Jessica

1
Tak, magazyn lokalny jest na ogół najbardziej odpowiednim miejscem do przechowywania go po stronie klienta. Musisz mieć do czynienia z XSS - nie jestem ekspertem w programowaniu stron internetowych, ale spójrz na tę odpowiedź stackoverflow.com/a/40376819/1810447 i wyszukaj „Jak chronić się przed XSS”
The Tahaan

1
W swoim komentarzu nie wspominasz o rozwiązaniu opartym na pamięci podręcznej + tokenie sesji. Brzmi to dla mnie "lepiej" niż stół JWT + "zabite tokeny", ponieważ z tą tabelą "zabitych tokenów" i tak potrzebujesz dostępu do bazy danych, który będziesz miał również z sesjami + cache (to też jest małe). A utrwalanie JWT jest bardziej bolesne w implementacji niż trwałe sesje, ponieważ musisz grać z refresh_tokenem (więc dwoma tokenami do utrzymania) ... Każdy komentarz byłby naprawdę doceniony ... zwłaszcza jeśli masz jakąś liczbę, aby pokazać, jak JWT + kill_table jest wydajniejsze niż sesje + pamięć podręczna ;-)
tobiasBora

2
@TheTahaan localStorage nie jest zalecane do przechowywania tokenów JWT. Udostępniony link również o tym wspomina. Ten blog zawiera dobre wyjaśnienie, dlaczego tokeny JWT nie powinny być przechowywane w magazynie localStorage.
Harke,

40

Krótka odpowiedź brzmi: brak.

Dłuższa wersja to:

Zaimplementowałem tokeny JWT do zarządzania sesjami po przeczytaniu tego zalecenia w dokumentacji GraphQL :

Jeśli nie znasz żadnego z tych mechanizmów uwierzytelniania, zalecamy użycie express-jwt, ponieważ jest to proste bez poświęcania przyszłej elastyczności.

Wdrożenie było rzeczywiście proste, ponieważ dodało tylko trochę złożoności. Jednak po jakimś czasie zacząłem (tak jak Ty) zastanawiać się, jakie są korzyści. Okazuje się, że jest bardzo niewiele (lub prawdopodobnie nie ma) dla JWT, jeśli chodzi o zarządzanie sesjami, co szczegółowo wyjaśnia ten post na blogu:

Przestań używać JWT do sesji


0

Moje dwa centy, które po drodze dodają kontrastu do słynnego wpisu na blogu joepie91.

Biorąc pod uwagę, że dzisiejsze (i jutrzejsze) aplikacje są (w większości) natywne dla chmury
Istnieje ekonomiczne korzyści wynikające z bezstanowego uwierzytelniania JWT , które skaluje się wraz ze skalą aplikacji:
Aplikacje w chmurze ponoszą koszty wraz z każdym wdechem .
Koszt ten zmniejsza się, gdy użytkownicy nie muszą już uwierzytelniać się „w” magazynie sesji.

Przetwarzanie
Prowadzenie sklepu sesyjnego 24/7 kosztuje.
Rozwiązania oparte na pamięci nie mogą ujść na sucho w świecie K8S, ponieważ strąki są efemeryczne.
Przyklejone sesje nie będą dobrze funkcjonować z dokładnie tego samego powodu.

Przechowywanie
Przechowywanie danych kosztuje. przechowywanie danych na dysku SSD kosztuje jeszcze więcej.
Operacje związane z sesją muszą być rozwiązywane szybko, więc napęd optyczny nie wchodzi w grę.

We / wy
Niektórzy dostawcy usług w chmurze pobierają pieniądze za operacje we / wy związane z dyskami.

Przepustowość
Niektórzy dostawcy usług w chmurze pobierają opłaty za aktywność sieciową między instancjami serwera.
Ma to zastosowanie, ponieważ jest prawie pewne, że interfejs API i magazyn sesji są oddzielnymi instancjami.

Klastrowanie magazynu sesji
Koszt eskaluje wszystkie wyżej wymienione koszty jeszcze bardziej.


„Rozwiązania oparte na pamięci nie mogą ujść na sucho w świecie K8S, ponieważ strąki są efemeryczne” Nie wiem, co masz na myśli. Redis zdecydowanie działa w środowisku K8S, a pod redis zawodzi wystarczająco często, aby wpłynąć na użytkowników, wydaje się bardzo mało prawdopodobne.
quietContest

@quietContest Osobiście wolę nie zajmować się prawdopodobieństwem podczas tworzenia oprogramowania. Poza tym, pomijając stabilność rozwiązania, atak może spowodować awarię oprogramowania i ponowne uruchomienie podsystemów, co może spowodować utratę sesji. Z tego powodu wybrałbym rozwiązanie oparte na JWT.
Eyal Perry

1
„Osobiście wolę nie zajmować się prawdopodobieństwem podczas tworzenia oprogramowania”. Myślę, że wszyscy wolelibyśmy to, dlatego nie powinniśmy projektować systemów, które polegają na magazynach danych w pamięci, które nigdy nie zawodzą, ponieważ prawdopodobieństwo tego wydaje się dość wysokie. Jeśli chodzi o drugą kwestię, jeśli masz atakującego, który jest w stanie konsekwentnie wyłączać Twoją instancję redis, rozwiązanie tego prawdopodobnie nie wymaga użycia tokeny JWT.
quietContest

@quietContest konsekwentnie lub raz w życiu jest dla mnie tym samym w tym aspekcie. tj. dobrze przeprowadzony atak DDoS może spowodować „wylogowanie użytkowników” przez serwer. Nie wpływa to dobrze na reputację niezawodności oprogramowania. Myślę, że redis i tak jest przesadą w zarządzaniu sesjami. To kosztuje i musi być skalowane, podczas gdy (bezpieczne) przechowywanie JWT w pliku cookie nie.
Eyal Perry

1
@quietContest Dziękuję za wkład, uwielbiam dyskusję!
Eyal Perry

0

Miałem podobne pytanie, wybierając między JWT a tokenem + pamięcią podręczną do uwierzytelniania użytkownika.

Po przeczytaniu tych artykułów jest dla mnie jasne, że korzyści, które obiecuje JWT, nie wyprzedzają problemów, które przynosi. Tak więc token + cache (Redis / Memcached) to droga dla mnie.

Auth Headers vs JWT vs Sessions - Jak wybrać właściwą technikę autoryzacji dla interfejsów API

Techniki uwierzytelniania dla interfejsów API

Przestań używać jwt do sesji

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.