Spring Boot i logowanie(?) z wykorzystaniem JWT

0

Cześć,

piszę rest api i stronę www z back-endem w javie z użyciem spring boota. Do tego w przyszłości będę chciał to rozwinąć o aplikację mobilną. Uświadczyłem problemu na etapie połączenia strony z api. O tyle o ile mogę za pomocą JS komunikować się z API to mam problem z uwierzytelnianiem użytkowników. W końcu nie chcę aby każdy miał możliwość korzystania ze wszystkich funkcji API. Póki co działa to tak że na stronę mogę się zalogować za pomocą mechanizmu sesji, a JWT wykorzystuję przy api (tutaj bawiłem się postmanem tylko). Obie rzeczy tworze jako oddzielne aplikacje i teraz chciałbym to jakoś połączyć. Dopiero zaczynam przygodę z tym "projektem" więc póki co istnieją tylko testowe widoki i endpointy którymi sprawdzam czy autoryzacja i role działają.

  1. Czy jest jakaś możliwość aby przy logowaniu do strony w tym samym czasie pobrać sobie JWT z api i trzymać jednocześnie sesję oraz token i potem korzystając z połączenia do api przez js przekazywać jwt? Jeśli tak to jak to zrobić i czy w ogóle tak to powinno wyglądać.
  2. Jako drugi pomysł mam po prostu korzystanie z api na back-endzie w javie (jeszcze nie wiem jak ale jakoś musi się dać). Sesja, która mi trzyma użytkownika na stronie dopuszczałaby do konkretnych endpointów w aplikacji webowej i te endpointy dopiero komunikowałyby się z api.
  3. trzeciego pomysłu nie mam, może to powinno wyglądać jeszcze zupełnie inaczej?
2

A więc tak - pytanie czy korzystasz z jakiegoś zewnętrznego serwera autoryzującego, czy samemu generujesz JWT. Generalnie to:

  1. Możesz stworzyć endpoint np GET /token który by zwracał JWT w przypadku aktualnie zalogowanego usera, 401 w przeciwnym razie. Wtedy z frontu byś uderzał pod ten endpoint - jeśli jesteś już wcześniej zalogowany, to dostaniesz token. Jeśli nie byłeś, to dostaniesz 401, czyli wiesz że musisz się zalogować. Później, możesz JWT trzymać na froncie, często się przyjmuje że w localStorage. ALE UWAGA - obiekty tam trzymane mogą być łatwo podejrzane przez kogoś śledzącego ruch - aczkolwiek z tym się raczej nic nie zrobi, ponieważ na tym założeniu się właśnie opiera idea tokenów - mając token, można bezstanowo się logować. Dobrą praktyką wtedy jest żeby te tokeny miały dosyć krótki czas trwania. Jeśli chcesz być super-hiper-zabezpiczony, to możesz pomyśleć o stworzeniu tzw "blacklist tokens", gdzie będziesz umieszczać jakieś przedawnione już dawno tokeny

  2. Możesz. Wtedy JWT nie jest trzymany na froncie, więc jest jeszcze bezpieczniej. A komunikując się service-to-service, to już znowu masz różne sposoby authentykacji - ale JWT jest spoko.

  3. Są różne sposoby, ale generalnie myślę że JWT na froncie jest potrzebny w przypadku, kiedy z frontu komunikujemy się do różnych domen. Jeśli integrację z jakimiś third party API robi backend, to nawet łatwiej.

0

Dziękuję bardzo za odpowiedź, rozjaśniłeś mi sytuację w ogromnym stopniu.

Odpowiadając na twoje pytanie token generuję samemu. Mam dodane filtry autentykacji i autoryzacji. Korzystałem między innymi z tego poradnika

Refresh token póki co nie istnieje ale jak się podszkolę z jego działania, zalet, wad itp itd to być może będę chciał z tego skorzystać.
Co do komunikacji z różnymi api to planuję jeszcze skorzystać z jakiś map (być może googla ale jeszcze nie wiem).

Nie ukrywam, że najbardziej mi się podoba pierwszy pomysł.
Chciałbym się tylko upewnić czy dobrze Cie zrozumiałem, miałoby to działać tak:

  1. Uderzam pod odpowiedni endpoint weba.
  2. Tam sprawdzam czy jestem zalogowany (patrzy po sesji).
    a) Jeśli jestem to back-end webowej apki komunikuje sie z api, pobiera token i mi go przekazuje (albo back-end aplikacji webowej generuje token dla api? To mi się nie widzi).
    b) Jak nie jestem zalogowany to po prostu rzucam 401.
  3. (W przypadku pomyślnego pobrania tokenu) Mam token, trzymam go lokalnie i potem tylko wrzucam w header do zapytania do api.

1 użytkowników online, w tym zalogowanych: 0, gości: 1