BackEnd do strony www Pomoc

0

Witam. Tworzymy ze znajomymi projekt do szkoły i trochę naprowadzenia mnie na odpowieny kierunek.
Reszta osób jest odpowiedzialna za frontend natomiast ja i jeszcze jeden kolega za backend. Chciałbym napisać jakieś rest api, którę przekazywało by informację na stronę i okazało się że przeszkodą dla mnie jest system logowania, ponieważ chciałbym to zrobić w miarę poprawnie jak na pierwszy poważniejszy projekt w springu i potrzebuję lekkiego naprowadzenia jakby to miało wyglądać.
Dodam, że frontend będzię pisany w reakcie a samo API będzię prawdopodobnie na osobnym serwerzę i będzię podpięte pod MySQL za pomocą JPA.
O czym powinienem poczytać ?
W jaki sposób przekazywać do API Login i hasło ?

1

Tutaj jest naprawdę sporo rzeczy do nauki. Po pierwsze powinieneś poczytać o wzorcach programowania ,które pomogą ci odizolować poszczególne warstwy api. Tak naprawdę warstw powinno być co najmniej klika kontroler,serwis,repozytorium czym się one zajmują doczytaj sam. Na pewno musisz także poczytać czym jest ORM oraz walidacja danych oczywiści jeszcze tak naprawdę potrzebowałbyś dowiedzieć się masę innych rzeczy ale to na pewno nie jest do opisania w ,krótkim poście na forum. Co do samego logowania to dane przekazujesz w body requesta do serwera koniecznie postem, i na jego podstawie generujesz odpowiedni token (obecnie najczęściej stosowany standardem zabezpieczania api jest outh2), musisz jednak pamiętać by nie bawić się w implementacje tych algorytmów samemu ponieważ ich implementacja wymaga niesamowitej wiedzy i naprawdę dużej ilości testów tak by mogły być one bezpieczne dlatego polecam użyć gotowego rozwiązania. To tak w bardzo telegraficznym skrócie ale co więcej da się na forum napisać. No może ,że jeszcze warto poczytać czym są corsy i dlaczego tokeny najlepiej trzymać w ciasteczkach httponly.

Ps. No i oczywiście requesty z logowaniem muszą być na https jeśli mowa o produkcji.

2

Ogólna idea jest taka, że po zalogowaniu backend zwraca token (np. JWT), który po stronie przeglądarki zapisujesz np. w Cookie i dodajesz do każdego requestu w nagłówku (robi to jakiś globalny interceptor po stronie frontu). Podrzucam garść linków, powinieneś coś z tego skleić.

https://spring.io/guides/tutorials/spring-security-and-angular-js/

https://www.powerupcloud.com/securing-spring-boot-and-react-js-with-spring-security-using-jwt-authentication/

https://medium.com/@mind_sFlight/basic-authentication-with-angular-7-and-spring-security-6fd140efc031

Możesz również wygenerować gotową aplikację Spring+React i podpatrzyć jak to robi jhipster - tak się kiedyś uczyłem ;) https://www.jhipster.tech/security/

EDIT: bezpieczne przechowywanie JWT https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/#jwt_vs_session

1

Jeżeli możesz, to użyj zwyczajnie Firebase. Użytkownik loguje się za pomocą zewnętrznego serwisu, ty dostajesz token JWT który daje się dość łatwo sprawdzić. Lista kont użytkowników jest po stronie Firebase, masz od razu możliwość uwierzytelniania za pomocą Google i chyba Facebook, usługa z tego co pamiętam jest za darmo. Serio, jeżeli nie ma jakichś bardzo szczególnych powodów do zaimplementowania tego samodzielnie, to warto używać takich usług Jest jeszcze parę innych serwisów np. Auth0, ale nie pamiętam, czy mają jakieś darmowe wersje.

Najprostsza możliwość to wysyłanie z front endu pobranego od użytkownika username i password w nagłówku każdego żądania Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l Ten dziwny ciąg znaków to usernam:password zakodowane w Base64.
Po stronie serwera, przed obsłużeniem każdego żądania sprawdzasz, czy w bazie danych jest już taki użytkownik i czy hasło się zgadza. Hasła nie wolno trzymać w bazie w formie jawnej, więc trzeba użyć jakiejś funkcji hashującej (np 'bcrypt' SHA256, `HMAC, ) i wynik trzymać w bazie. Współcześnie używa się wielu rund szyfrujących (czyli kilka tysięcy razy stosuje się tę samą funkcję), żeby zwiększyć moc obliczeniową potrzebną do skutecznego ataku brute force, polegającego na sprawdzaniu wszystkich możliwych kombinacji hasła czy nie da się z nich wygenerować identycznego hash'a. Dodatkowo trzeba pamiętać o soleniu hashy - czyli dodawaniu do hasha jakiegoś dodatkowego elementu (np. nazwy użytkownika), żeby hashe takich samych haseł dla różnych użytkowników były różne, oraz by zabezpieczyć sie przed atakiem z użyciem rainbow tables.

Powyższy sposób ma problem z wydajnością, ponieważ musisz wyliczyć hash dla hasła przy każdym żądaniu (a celowo zrobiliśmy to kosztowną operacją), oraz odpytać bazę danych o istnienie takiego użytkownika. Rozwiązaniem dobrym będzie więc wykorzystanie hasła użytkownika jedynie do wygenerowania tokenu JWT (taki cyfrowy dowód osobisty) i weryfikacja poprawności tokenu (wystarczy sprawdzić poprawność podpisu). Czyli w praktyce odtwarzasz w ten sposób to co masz w Firebase.

0

A czy podczas przesyłania danych z formularza do mojego API powinniśmy szyfrować też nazwę używkownika, czy tylko hasło wystarczy ?

3

Tak naprawdę nic z tego nie ma potrzeby szyfrować ,za szyfrowanie jest odpowiedzialny protokół https i dodatkowe szyfrowanie hasła średnio ma sens, ogólnie to można ale według standardu outh2 nic z tych danych się nie szyfruje.

1

@Rozumek29: Powinieneś wszystko szyfrować na poziomie protokołu https, w szczególności nie powinno dać się wysłać username i hasła po standardowym http. Tu masz darmowe ceryfikaty: https://letsencrypt.org/ jakąś domenę sobie musisz do tego zorganizować, pewnie też znajdziesz coś za darmo .

0

@piotrpo: O!, wielke dzięki przyda się darmowy certyfikat. Bo domena zarówno projektu który należy do mojej szkoły nie ma certyfikatu więc zaczynałem obawiać się o to protokół HTTPS

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