Przepływ tokenu odświeżania JWT

129

Buduję aplikację mobilną i używam JWT do uwierzytelniania.

Wydaje się, że najlepszym sposobem na to jest sparowanie tokena dostępu JWT z tokenem odświeżania, aby móc wygasać token dostępu tak często, jak chcę.

  1. Jak wygląda token odświeżania? Czy to losowy ciąg? Czy ten ciąg jest zaszyfrowany? Czy to kolejny JWT?
  2. Token odświeżania byłby przechowywany w bazie danych w modelu użytkownika w celu uzyskania dostępu, prawda? Wygląda na to, że w tym przypadku powinien być zaszyfrowany
  3. Czy odesłałbym token odświeżania z powrotem po zalogowaniu użytkownika, a następnie pozwoliłbym klientowi uzyskać dostęp do oddzielnej trasy w celu pobrania tokenu dostępu?
jtmarmon
źródło
3
Uwaga, jeśli używasz tokenów odświeżania, powinieneś zapewnić użytkownikom możliwość unieważnienia ich w interfejsie użytkownika. Zaleca się również automatyczne wygasanie ich, jeśli nie są używane np. Przez miesiąc.
Vilmantas Baranauskas
1
@jtmarmon: jak przechowywać token odświeżania po stronie klienta? Mam na myśli urządzenie z Androidem z bezpieczeństwem?
j10

Odpowiedzi:

39

Zakładając, że chodzi o OAuth 2.0, ponieważ chodzi o tokeny JWT i tokeny odświeżania ...:

  1. tak jak token dostępu, w zasadzie token odświeżania może być wszystkim, w tym wszystkimi opcjami, które opisujesz; token JWT może być użyty, gdy serwer autoryzacji chce być bezstanowy lub chce narzucić klientowi prezentującemu go pewnego rodzaju semantykę „dowodu posiadania”; zwróć uwagę, że token odświeżania różni się od tokena dostępu tym, że nie jest prezentowany serwerowi zasobów, ale tylko serwerowi autoryzacji, który go wystawił, więc niezależna optymalizacja walidacji dla tokenów JWT-as-access nie przechowywać dla tokenów odświeżania

  2. zależy to od bezpieczeństwa / dostępu do bazy danych; jeśli dostęp do bazy danych mają inne strony / serwery / aplikacje / użytkownicy, to tak (ale Twój przebieg może się różnić w zależności od miejsca i sposobu przechowywania klucza szyfrowania ...)

  3. serwer autoryzacji może jednocześnie wystawiać tokeny dostępu i tokeny odświeżania, w zależności od nadania używanego przez klienta do ich uzyskania; specyfikacja zawiera szczegóły i opcje dotyczące każdego standardowego grantu

Hans Z.
źródło
31
2. Powinieneś przechowywać hash tokena odświeżania w swojej bazie danych, a następnie porównać hash tokena odświeżania użytkownika z przechowywanym hashem. Zasada „nie przechowuj haseł w postaci zwykłego tekstu w swojej bazie danych” znajduje się tutaj. Potraktuj token jak losowe hasło utworzone dla użytkownika.
Rohmer
2
Ponadto, jeśli chcesz zapewnić większe bezpieczeństwo, wykonaj również rotację tokenu odświeżania. Znaczenie tego jest już wspomniane w dokumencie ITEF RFC 6749 . Jeśli zostanie poprawnie wdrożony, może to również pomóc w zidentyfikowaniu scenariusza kradzieży tokena, tj. Odświeżenie tokena zostało skradzione przez atakującego. Jeśli szukasz lepszego wyjaśnienia,
przejdź
85

Poniżej znajdują się czynności umożliwiające unieważnienie tokenu dostępu JWT:

  1. Gdy się zalogujesz, wyślij 2 tokeny (token dostępu, token odświeżania) w odpowiedzi do klienta.
  2. Token dostępu będzie miał krótszy czas wygaśnięcia, a odświeżanie będzie miało długi czas wygaśnięcia.
  3. Klient (Frontend) będzie przechowywać token odświeżania w swojej lokalnej pamięci i token dostępu w plikach cookie.
  4. Klient będzie używał tokenu dostępu do wywoływania interfejsów API. Ale kiedy wygaśnie, wybierz token odświeżania z magazynu lokalnego i wywołaj interfejs API serwera uwierzytelniania, aby uzyskać nowy token.
  5. Twój serwer uwierzytelniający będzie miał udostępniony interfejs API, który zaakceptuje token odświeżania, sprawdzi jego ważność i zwróci nowy token dostępu.
  6. Po wygaśnięciu tokena odświeżania użytkownik zostanie wylogowany.

Daj mi znać, jeśli potrzebujesz więcej informacji, mogę również udostępnić kod (rozruch Java + Spring).

W przypadku pytań:

P1: To kolejny JWT z mniejszą liczbą zgłoszonych roszczeń i długim czasem wygaśnięcia.

P2: Nie będzie w bazie danych. Backend nie będzie nigdzie przechowywać. Po prostu odszyfrują token kluczem prywatnym / publicznym i zweryfikują go również z czasem wygaśnięcia.

P3: tak, zgadza się

Bhupinder Singh
źródło
28
Myślę, że token JWT powinien być przechowywany w, localStoragea refreshTokenpowinien być przechowywany w pliku httpOnly. refreshToeknMogą być wykorzystywane, aby otrzymać nowy JWT więc musi być traktowane ze szczególną ostrożność.
Tnc Andrei
2
Dzięki, co masz na myśli, przechowując w httpOnly? Dlaczego nie przechowywać obu w localStorage?
Jay
8
Brakuje mi korzyści płynących z używania tokena odświeżania, czy nie byłby taki sam sposób przedłużenia ważności tokena dostępu?
user2010955
3
@Jay Według Microsoft Developer Network, HttpOnly jest dodatkową flagą zawartą w nagłówku odpowiedzi HTTP Set-Cookie. Użycie flagi HttpOnly podczas generowania pliku cookie pomaga zmniejszyć ryzyko, że skrypt po stronie klienta uzyska dostęp do chronionego pliku cookie (jeśli przeglądarka go obsługuje).
shadow0359
23
Punkt 2 jest wysoce niedokładny. Token odświeżania MUSI być przechowywany po stronie serwera. Nie powinieneś wykorzystywać „samodzielnej” właściwości JWT do odświeżania tokenu. W ten sposób nie masz możliwości unieważnienia tokenów odświeżania poza zmianą klucza prywatnego.
Jai Sharma
26

Oparte na tej implementacji z Node.js JWT z tokenem odświeżania :

1) W tym przypadku używają uid i nie jest to JWT. Kiedy odświeżają token, wysyłają token odświeżania i użytkownika. Jeśli zaimplementujesz go jako token JWT, nie musisz wysyłać użytkownika, ponieważ zrobiłby to wewnątrz tokena JWT.

2) Wdrażają to w oddzielnym dokumencie (tabeli). Ma to dla mnie sens, ponieważ użytkownik może być zalogowany w różnych aplikacjach klienckich i może mieć token odświeżania według aplikacji. Jeśli użytkownik utraci urządzenie z zainstalowaną jedną aplikacją, token odświeżania tego urządzenia może zostać unieważniony bez wpływu na inne zalogowane urządzenia.

3) W tej implementacji odpowiada na metodę logowania zarówno za pomocą tokena dostępu, jak i tokena odświeżania. Wydaje mi się to poprawne.

David
źródło
Mówiąc „1) W tym przypadku używają uid…” czy miałeś na myśli UUID?
ozanmuyes
A co z tą prostszą implementacją - Wydanie JWT - wyślij starszy token JWT, gdy chcesz odświeżyć - (możesz sprawdzić iatw oknie) - ponownie wystaw nowy na podstawie poprzedniego
adonese
@adonese wysyłając tylko to, JWTco chcesz mieć w refresh_tokenśrodku? Jeśli tak, OAuth RFC 6749 wyraźnie mówi, aby nie wysyłać refresh_tokendo serwera zasobów (i JWTjest wysyłany do serwerów zasobów): tools.ietf.org/html/rfc6749#section-1.5
Brenno Costa