Najlepsze praktyki unieważniania JWT podczas zmiany haseł i wylogowania w węźle.js? [zamknięte]

Chciałbym poznać najlepsze praktyki unieważniania JWT bez uderzania db podczas zmiany hasła/wylogowania.

Mam pomysł poniżej, aby obsłużyć powyżej 2 przypadków, trafiając do bazy danych użytkowników.

1.W przypadku zmian hasła, sprawdzam hasło (hashed) przechowywane w DB użytkownika.

2.W przypadku wylogowania zapisuję czas ostatniego wylogowania w DB użytkownika, stąd porównując czas utworzenia tokena i czas wylogowania, mogę w stanie unieważnić ten przypadek.

Ale te 2 przypadki przychodzą kosztem trafienia dB użytkownika za każdym razem, gdy użytkownik trafi w api. Każda najlepsza praktyka jest doceniana.

Aktualizacja: Nie sądzę, że możemy unieważnić JWT bez uderzania db. Więc wymyśliłem rozwiązanie. Zamieściłem swoją odpowiedź, jeśli masz jakiekolwiek obawy, jesteś mile widziany.

Author: Gopinath Shiva, 2015-02-27

5 answers

Gdy nie jest używany token odświeżania:

1.Podczas zmiany hasła: gdy użytkownik zmienia swoje hasło, zanotuj czas zmiany hasła w db użytkownika, więc gdy czas zmiany hasła jest większy niż czas utworzenia tokena, token nie jest ważny. Stąd pozostała sesja zostanie wkrótce wylogowana.

2.Gdy użytkownik wyloguje się: gdy użytkownik wyloguje się, Zapisz token w oddzielnym DB (powiedzmy: InvalidTokenDB i usuń token z Db, gdy token wygasa). W związku z tym użytkownik wylogowuje się z danego urządzenia, a jego sesje na innym urządzeniu pozostają niezakłócone.

Dlatego podczas unieważniania JWT postępuję zgodnie z poniższymi krokami:

  1. sprawdź, czy token jest ważny, czy nie.
  2. jeśli jest poprawny, sprawdź, czy jest obecny w invalidTokenDB (bazie danych, w której wylogowane tokeny są przechowywane do czasu ich wygaśnięcia).
  3. jeśli nie jest obecny, Sprawdź czas wytworzenia tokenu i czas zmiany hasła w db użytkownika.
  4. If changed czas hasła

Dotyczy powyższej metody:

  1. dla każdego żądania api, muszę wykonać wszystkie powyższe kroki, które mogą mieć wpływ na wydajność.

W przypadku odświeżania tokena: z wygaśnięciem tokenu dostępu jako 1 dzień, odśwież token jako dożywotnia Ważność

1. Podczas zmiany hasła: Gdy użytkownik zmieni swoje hasło, Zmień token odświeżania użytkownika. Stąd Pozostałe sesja zostanie wkrótce wylogowana.

2. Gdy użytkownik wyloguje się: gdy użytkownik wyloguje się, Zapisz token w oddzielnym DB (powiedzmy: InvalidTokenDB i usuń token z Db, gdy token wygaśnie). W związku z tym użytkownik wylogowuje się z danego urządzenia, a jego sesje na innym urządzeniu pozostają niezakłócone.

Dlatego podczas unieważniania JWT postępuję zgodnie z poniższymi krokami:

  1. sprawdź czy token jest ważny czy nie
  2. jeśli jest ważny, sprawdź czy token jest obecny w InvalidTokenDB.
  3. jeśli nie jest obecny, sprawdź token odświeżania za pomocą tokenu odświeżania w userDB.
  4. If equals, then its a valid token

Dotyczy powyższej metody:

  1. dla każdego żądania api, muszę wykonać wszystkie powyższe kroki, które mogą mieć wpływ na wydajność.
  2. Jak unieważnić token odświeżania, ponieważ token odświeżania nie ma ważności, jeśli jest używany przez hakera, nadal uwierzytelnianie jest poprawne, żądanie zakończy się sukcesem zawsze.

Uwaga : chociaż Hanz zasugerował sposób zabezpieczenia tokenu odświeżania w używanie tokenu Refesh w uwierzytelnianiu opartym na tokenie jest zabezpieczone?Nie mogłem zrozumieć, co on mówi. Każda pomoc jest mile widziana.

Więc jeśli ktoś ma miłe sugestie, Wasze komentarze są mile widziane.

UPDATE: Dodaję odpowiedź okrywać aplikacja nie potrzebuje odśwież token z dożywotnim wygaśnięciem. Ta odpowiedź została udzielona przez Sudhanshu ( https://stackoverflow.com/users/4062630/sudhanshu-gaur ). dzięki Sudhanshu. Więc uważam, że jest to najlepszy sposób, aby to zrobić,

Gdy nie jest potrzebny token odświeżania i nie ma wygaśnięcia tokenów dostępu:

Podczas logowania użytkownika, Utwórz token logowania w jego bazie danych użytkowników bez czasu wygaśnięcia.

Dlatego podczas unieważniania JWT, wykonaj poniższe kroki,

  1. Pobierz informacje o użytkowniku i sprawdź, czy token znajduje się w jego bazie danych. Jeśli pozwolicie.
  2. kiedy użytkownik wylogowuje się, usuwa tylko ten token ze swojej bazy danych użytkowników.
  3. gdy użytkownik zmieni hasło, usuń wszystkie tokeny z bazy danych użytkownika i poproś go o ponowne zalogowanie.

Tak więc przy takim podejściu nie trzeba przechowywać ani tokenów wylogowania w bazie danych do czasu ich wygaśnięcia, ani przechowywać czasu tworzenia tokenów przy zmianie hasła, co było potrzebne w powyższych przypadkach. Jednak uważam, że to podejście sprawdza się tylko wtedy, gdy aplikacja ma wymagania bez odświeżania token potrzebne i nie wygaśnięcie tokenów.

Jeśli ktoś ma obawy z tym podejściem, proszę dać mi znać. Wasze komentarze mile widziane:)

 58
Author: Gopinath Shiva,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:17

Nie znam sposobu na arbitralne unieważnienie tokena bez angażowania bazy danych w taki czy inny sposób.

Uważaj z Approach 2, jeśli Twoja usługa jest dostępna na kilku urządzeniach. Rozważ następujący scenariusz...

  • użytkownik loguje się za pomocą iPada, Token 1 wydany i przechowywany.
  • użytkownik loguje się na stronie. Token 2 wydany. Użytkownik wylogowuje się.
  • użytkownik próbuje korzystać z iPada, Token 1 został wydany przed wylogowaniem się użytkownika ze strony, Token 1 teraz uznany za nieważny.

Warto przyjrzeć się idei odświeżania tokenów, chociaż wymagają one również przechowywania bazy danych.

Zobacz także tutaj dla dobrej dyskusji dotyczącej podobnego problemu, szczególnie rozwiązania IanB, które zapisałoby niektóre wywołania db.

Proponowane rozwiązanie Osobiście podchodziłbym do tego w ten sposób...użytkownik uwierzytelnia się, wystawiając token dostępu z krótkim terminem wygaśnięcia (powiedzmy 15 min) i token odświeżania ważny albo na znacznie dłuższy okres, albo na czas nieokreślony. Przechowuje rekord tego odświeżania tokena w db.

Gdy użytkownik jest "aktywny", za każdym razem wystawiaj nowy token auth (ważny przez 15 minut za każdym razem). Jeśli użytkownik nie jest aktywny przez ponad 15 minut, a następnie wykonuje żądanie(więc używa wygasłego jwt), Sprawdź ważność tokenu odświeżania. Jeśli jest poprawny (łącznie z db check), wydaj nowy token auth.

Jeśli użytkownik "wyloguje się" albo na urządzeniu, albo przez stronę internetową, to zniszczy oba uzyskaj dostęp do odświeżania tokenów po stronie klienta i co ważne anuluj Ważność używanego tokenu odświeżania. Jeśli użytkownik zmieni hasło na dowolnym urządzeniu, cofnie wszystkie tokeny odświeżania, zmuszając go do ponownego zalogowania się, gdy tylko wygaśnie token dostępu. To pozostawia "okno niepewności", ale jest to nieuniknione bez uderzania db za każdym razem.

Zastosowanie tego podejścia otwiera również możliwość "cofnięcia" dostępu do określonych urządzeń, jeśli jest to wymagane, jak widać w wielu główne aplikacje internetowe.

 13
Author: DevFox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:17:59

Nie jestem pewien, czy coś mi tu umyka, ale uważam, że przyjęta odpowiedź jest bardziej skomplikowana niż jest to konieczne.

Widzę, że db musi zostać trafiony, aby zweryfikować lub unieważnić token dla każdego żądania api, jednak całkowity proces mógł być prostszy, ponieważ widzę tutaj rzeczy.

Za każdym razem, gdy tworzony jest jwt, tj. podczas logowania lub zmiany/resetowania hasła, należy wstawić jwt z identyfikatorem userid do tabeli i zachować jti (w zasadzie numer uuid) dla każdego jwt. Ta sama wit wchodzi do JWT też. W praktyce jti jednoznacznie identyfikuje jwt. Użytkownik może mieć wiele JWT w tym samym czasie, gdy konto jest dostępne z wielu urządzeń lub przeglądarek w takim przypadku, jti odróżnia urządzenie lub agenta użytkownika.

Więc schemat tabeli będzie, jti / userId. (i podstawowy klucz kursu)

Dla każdego api sprawdź, czy jti jest w tabeli, co oznacza, że jwt jest poprawne.

Gdy użytkownik zmieni lub zresetuje hasło, usuń wszystkie jti z tego userId z db. Utwórz i wstaw nowy jwt z nowym jti do tabeli. Spowoduje to unieważnienie wszystkich sesji z wszystkich innych urządzeń i przeglądarek z wyjątkiem tego, który zmienił lub zresetował hasło.

Po wylogowaniu się użytkownika usuń ten konkretny jti tego użytkownika, ale nie wszystkie. Nie byłoby jednego logowania, ale nie jednego wylogowania. Więc kiedy użytkownik wyloguje się, nie powinien być wylogowany ze wszystkich urządzeń. Jednak usunięcie wszystkich wit spowoduje wylogowanie się ze wszystkich urządzeń też.

Więc byłaby to jedna tabela i brak porównań dat. Również byłoby tak samo, jeśli token odświeżania jest używany, czy nie.

Jednak, aby zminimalizować zakłócenia db i możliwe opóźnienia, użycie pamięci podręcznej z pewnością pomogłoby zmniejszyć czas przetwarzania.

Uwaga: proszę uzasadnić, jeśli nie głosujesz.

 6
Author: Amruta-Pani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-06 07:45:50

Jeśli użytkownik zmienia swoje hasło, trafisz tam w db. Ale nie chcesz trafić do db o autoryzację?

Odkryłem korzyści płynące z przechowywania ciągów dla każdego użytkownika, a globalny współdzielony ciąg zaszyfrowany razem daje nam największą elastyczność w implementacji JWT. W tym konkretnym przypadku zachowałbym hash hasła do użycia z globalnym ciągiem i hashował je razem dla tajemnicy JWT.

 1
Author: Mark Essel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-30 15:04:43

Zgadzam się wyłącznie z @Gopinath odpowiedź po prostu chcę dodać jedną rzecz, że należy również usunąć czas zmiany hasła, gdy wszystkie tokeny wygasły na przykład załóżmy, że masz ustawiony czas wygaśnięcia 3 dni dla każdego tokena wygasnąć teraz zamiast po prostu normalnie zapisując czas zmiany hasła w bazie danych można również ustawić jego czas wygaśnięcia 3 dni, ponieważ jak oczywiście tokeny przed to będzie wygasł, więc nie trzeba sprawdzać dla każdego tokena ponownie, że czy jego czas wygaśnięcia jest większy niż zmiana czasu password time or not

 -1
Author: Sudhanshu Gaur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-11 17:32:55