Wciąż próbuję znaleźć najlepsze rozwiązanie bezpieczeństwa do ochrony interfejsu API REST, ponieważ liczba aplikacji mobilnych i interfejsu API rośnie z każdym dniem.
Próbowałem różnych sposobów uwierzytelniania, ale nadal mam pewne nieporozumienia, dlatego potrzebuję porady kogoś bardziej doświadczonego.
Pozwól mi powiedzieć, jak rozumiem te wszystkie rzeczy. Jeśli coś rozumiem źle, daj mi znać.
O ile interfejs API REST jest bezstanowy, a także ogólnie WEB, musimy wysyłać niektóre dane uwierzytelniające w każdym żądaniu (pliki cookie, token ....). Znam trzy szeroko stosowane mechanizmy uwierzytelniania użytkownika
Token z HTTPS. Używałem tego podejścia wiele razy, ponieważ jest wystarczająco dobry z HTTPS. Jeśli użytkownik poda prawidłowe hasło i login, w odpowiedzi otrzyma token i użyje go do dalszych żądań. Token jest generowany przez serwer i przechowywany, na przykład w tabeli osobno lub w tym samym miejscu, w którym przechowywane są informacje o użytkowniku. Tak więc dla każdego żądania serwer sprawdza, czy użytkownik ma token i czy jest taki sam jak w bazie danych. Wszystko jest bardzo proste.
Token JWT. Ten token jest opisowy, zawiera wszystkie niezbędne informacje o samym tokenie, użytkownik nie może zmienić na przykład daty ważności ani żadnego innego roszczenia, ponieważ ten token jest generowany (podpisany) przez serwer za pomocą tajnego słowa kluczowego. To również jasne. Ale jeden duży problem, osobiście dla mnie, jak unieważnić token.
OAuth 2. Nie rozumiem, dlaczego takie podejście powinno być stosowane, gdy komunikacja jest ustanawiana bezpośrednio między serwerem a klientem. O ile rozumiem, serwer OAuth służy do wydawania tokena z ograniczonym zakresem, aby umożliwić innym aplikacjom dostęp do informacji o użytkowniku bez przechowywania hasła i loginu. To świetne rozwiązanie dla sieci społecznościowych, gdy użytkownik chce się zarejestrować na jakiejś stronie, serwer może poprosić o uprawnienia do uzyskania informacji o użytkowniku, na przykład z Twittera lub Facebooka, i wypełnić pola rejestracyjne danymi użytkownika i tak dalej.
Zastanów się nad mobilnym klientem sklepu internetowego.
Pierwsze pytanie, czy wolę JWT niż token pierwszego typu? O ile potrzebuję zalogować / wylogować użytkownika na kliencie mobilnym, muszę zapisać gdzieś token lub w przypadku JWT, token powinien zostać unieważniony przy wylogowaniu. Do unieważnienia tokena stosuje się różne podejścia. Jednym z nich jest utworzenie listy nieprawidłowych tokenów (czarna lista). Hmm Tabela / plik będzie miał znacznie większy rozmiar niż gdyby token był przechowywany w tabeli i powiązany z użytkownikiem, a po prostu usunięty podczas wylogowywania.
Jakie są więc zalety tokena JWT?
Drugie pytanie dotyczące OAuth, czy powinienem z niego korzystać w przypadku bezpośredniej komunikacji z moim serwerem? Jaki jest cel jeszcze jednej warstwy między klientem a serwerem tylko do wydawania tokena, ale komunikacja nie będzie z oauth server, ale z serwerem głównym. Jak rozumiem, serwer OAuth jest odpowiedzialny tylko za udzielanie aplikacjom zewnętrznym uprawnień (tokenów) do uzyskiwania dostępu do prywatnych informacji użytkownika. Ale moja aplikacja klienta mobilnego nie jest firmą zewnętrzną.
Odpowiedzi:
Rozważ pierwszy przypadek. Każdy klient otrzymuje losowy identyfikator, który trwa przez czas trwania sesji - co może potrwać kilka dni, jeśli chcesz. Następnie przechowujesz informacje dotyczące tej sesji gdzieś po stronie serwera. Może to być plik lub baza danych. Załóżmy, że przekazujesz identyfikator za pomocą pliku cookie, ale możesz użyć adresu URL lub nagłówka HTTP.
Identyfikatory sesji / pliki cookie
Plusy:
Cons:
Tokeny internetowe JSON (JWT)
W drugim przypadku dane są przechowywane w JWT, który jest przekazywany zamiast na serwerze.
Plusy:
Cons:
Po stronie serwera potrzebny jest kod do generowania, sprawdzania poprawności i odczytu JWT. To nie jest trudne, ale jest trochę krzywej uczenia się i od tego zależy bezpieczeństwo.
Każdy, kto otrzyma kopię klucza podpisu, może utworzyć JWT. Możesz nie wiedzieć, kiedy to się stanie.
W niektórych bibliotekach był (jest?) Błąd, który akceptował dowolny JWT podpisany algorytmem „none”, aby każdy mógł tworzyć JWT, którym serwer ufałby.
Aby odwołać JWT przed jego upływem, musisz użyć listy odwołania. W ten sposób powrócisz do problemów z pamięcią po stronie serwera, których starałeś się uniknąć.
OAuth
Często OAuth służy do uwierzytelniania (tj. Tożsamości), ale może być wykorzystywany do udostępniania innych danych, takich jak lista treści zakupionych przez użytkownika i do pobrania. Można go również użyć do udzielenia dostępu do zapisu danych przechowywanych przez stronę trzecią. Możesz użyć OAuth do uwierzytelnienia użytkowników, a następnie użyć pamięci po stronie serwera lub JWT dla danych sesji.
Plusy:
Cons:
Różne
źródło
Zadaj sobie pytanie, dlaczego musisz unieważnić oryginalny token.
Użytkownik loguje się, generowany jest token i wyłącza się aplikacja.
Użytkownik naciska wylogowanie, generowany jest nowy token i zastępuje oryginalny token. Po raz kolejny wszystko jest w porządku.
Wygląda na to, że martwisz się sytuacją, w której oba tokeny wiszą w pobliżu. Co się stanie, jeśli użytkownik wyloguje się, a następnie w jakiś sposób złoży żądanie za pomocą zalogowanego tokena. Jak realistyczny jest ten scenariusz? Czy to tylko problem podczas wylogowania, czy jest wiele możliwych scenariuszy, w których wiele tokenów może stanowić problem?
Sam nie sądzę, że warto się martwić. Jeśli ktoś przechwytuje i dekoduje zaszyfrowane dane https, masz o wiele większe problemy.
Możesz zapewnić sobie dodatkową ochronę, umieszczając czas ważności na oryginalnym tokenie. Jeśli więc zostanie skradziony lub coś takiego, byłoby dobrze tylko przez krótki okres czasu.
W przeciwnym razie myślę, że musisz mieć informacje o stanie na serwerze. Nie umieszczaj na czarnej liście tokenów, ale zamiast tego umieść na białej liście podpis bieżącego tokena.
źródło
Możesz poradzić sobie z problemami JWT, o których wspomniałeś, przechowując wartość soli razem z użytkownikiem i używając soli jako części tokena dla użytkownika. Następnie, gdy musisz unieważnić token, po prostu zmień sól.
Wiem, że minęło kilka lat, ale teraz zrobiłbym to inaczej. Myślę, że zapewniłbym, że tokeny dostępu miały stosunkowo krótki okres użytkowania, powiedzmy godzinę. Będę również musiał używać tokenów odświeżania, które były stanowe na serwerze, a następnie, gdy chciałem zakończyć czyjąś sesję, odwołałem token odświeżania, usuwając go z serwera. Następnie po godzinie użytkownik zostanie wylogowany i będzie musiał zalogować się ponownie, aby odzyskać dostęp.
źródło