Najważniejsze zagadnienia, które musisz znać
5 godz. 53 min · JavaScript · Full-stack i Programowanie
Adam GospodarczykPrzesyłanie oraz transformacja danych to jeden z najważniejszych elementów działania każdej aplikacji. Dobre zrozumienie tego w jaki sposób odbywa się ten proces, daje równocześnie lepsze zrozumienie całej struktury oraz podejmowania decyzji projektowych. W tym kursie znajdziesz lekcje, które pozwolą Ci uporządkować wiedzę na temat protokołu HTTP oraz formatów wymiany danych.
REST oraz GraphQL to nadal nieodłączone zagadnienia tematu wymiany informacji w kontekście aplikacji webowych. Pomimo tego, że ich koncepcje zwykle są bardzo dobrze opisane w różnych źródłach, tak ich wykorzystanie "na produkcji" potrafi sprawić problemy. W szczególności gdy weźmiemy pod uwagę, wyjątki oraz fakt, że nie każda aplikacja będzie wymagać implementacji REST czy GraphQL w 100%. W tym kursie znajdziesz wiele praktycznych wskazówek związanych z pracą z REST API oraz wprowadzenie do pracy z GraphQL.
Niektóre błędy w aplikacji są bardzo pożądane, w szczególności gdy jasno informują użytkownika o tym, co się wydarzyło oraz o tym, co może z tym zrobić. Pomimo tego, że w wielu przypadkach opracowanie komunikatów leży w rękach osoby odpowiedzialnej za copywriting (i/lub ux writing), tak sama implementacja tych komunikatów odbywa się po stronie kodu. Nie rzadko okazuje się, że poprawna i skuteczna walidacja danych oraz obsługa błędów nie jest oczywista w "produkcyjnych" sytuacjach. W tym kursie znajdziesz najczęściej spotykane problemy oraz sposoby ich rozwiązania.
Bazy danych są praktycznie nieodłączną częścią każdej aplikacji. W roli full-stacka prędzej czy później przyjdzie Ci z nimi pracować a nie rzadko nawet projektować oraz rozbudowywać ich struktury. W tym kursie znajdziesz informacje o bazach danych, które pozwolą Ci je zrozumieć oraz od razu poznać użyteczne techniki, które pomogą Ci w pracy z nimi, zarówno na produkcji jak i w środowisku lokalnym czy testowym.
Nie wszystkie informacje w aplikacji są publiczne. Niektóre wprost nie mogą takie być. Z tego powodu niezbędne są sposoby na to aby poznać a potem weryfikować tożsamość użytkownika, by na jej podstawie przydzielać mu dostęp wyłącznie do zasobów, do których odczytywania posiada uprawnienia. Istnieje wiele technik, które umożliwiają zarządzanie dostępem do danych i w tym kursie poznasz najważniejsze z nich. Dowiesz się nie tylko w jaki sposób zabezpieczać dane ale poznasz też najpopularniejsze sposoby na to aby te zabezpieczenia łamać i obchodzić. Mając świadomość takiej możliwości, będziesz w stanie lepiej podejmować decyzje o tym jak projektować dostęp do informacji.
Istnieją problemy charakterystyczne dla niemal każdej aplikacji. W związku z ich powszechnością, istnieje też szereg rozwiązań lub sposobów na to, aby możliwie zredukować ich następstwa. Na przestrzeni lekcji tego kursu zobaczysz wiele przykładów, które pomogą Ci w codziennej pracy a niekiedy nawet, pozwolą uniknąć błędów, których konsekwencje nie zawsze występują natychmiast.
Kurs powstał z myślą o osobach, które chcą rozwijać się w roli full-stack web developera / developerki, przeprowadzając przez najważniejsze zagadnienia z obszaru wymiany, transformacji oraz przechowywania informacji w aplikacji oraz pomiędzy aplikacjami. Jeżeli potrzebujesz zobaczyć szeroką perspektywę tego, w jaki sposób dane przepływają pomiędzy różnymi częściami aplikacji, lub ugruntować swoją wiedzę na ten temat, to ten kurs jest miejscem, którego szukasz.
Następny w kolejce mechanizm uwierzytelnienia to 2.0.
W tym przypadku sytuacja jest nieco bardziej skomplikowana niż w każdym
wcześniejszym ze względu na to, że musimy zadbać o zdecydowanie więcej rzeczy.
Zasadniczo na tym etapie wykorzystamy już bazę danych oraz możliwość logowania
poprzez podanie loginu oraz hasła, które zostaną wykorzystane do tego, aby w
odpowiedni sposób porównać je z informacjami przechowywane w bazie, a
następnie zwrócić użytkownikowi Access token.
W naszym jednak przypadku nie będziemy wykorzystywać http only kuki, ponieważ na
to przyjdzie jeszcze czas, tylko zwyczajnie pokażę Ci prostszy sposób
polegający na zwróceniu Access tokena bezpośrednio w samej odpowiedzi.
A następnie też wykorzystamy ten token do
tego, aby wykonać kolejne zapytanie do naszego serwera.
Proponuję więc, abyśmy przeszli teraz do samego edytora.
Na początek uruchomimy tutaj serwer i niech on działa tutaj w tle, a następnie
przejrzymy sobie wszystkie pliki, które tutaj przygotowałem.
Jak widzisz, w porównaniu do projektu
uwzględniającego chociażby grafiki, jest tutaj zdecydowanie więcej plików.
Wynika to z faktu, że w pierwszej kolejności podłączamy tutaj mój głos i
kontaktujemy się bezpośrednio z lokalną bazą danych.
To wewnątrz niej będą przechowywane informacje na temat użytkowników.
W momencie, gdy MongoDB zainstalowane i uruchomione jest na moim systemie, jedyne
co muszę tutaj zrobić, to przekazać adres do tej bazy danych.
Następnie potrzebuję tutaj dwa moduły.
Jeden z nich będzie odpowiedzialny za obsługę samych użytkowników, a drugi za
kwestie dotyczące autoryzacji oraz uwierzytelnienia.
W moim przypadku chciałbym zarówno uwzględnić możliwość rejestrowania
użytkowników, jak też pobierania informacji na temat samego użytkownika.
Warto tutaj zaznaczyć, że to decyzją projektową jest to, czy sama rejestracja
czy też tworzenie nowego użytkownika znajduje się WZ z kontroler, czy raczej
bezpośrednio w kontrolerze, ale w moim przypadku raczej jestem za tym, aby
tworzenie nowego użytkownika było tam gdzie sami użytkownicy.
A jeżeli chodzi o samo logowanie to już znajduje się w module Auth.
W związku z tym jak widzisz mamy tutaj trzy ścieżki.
Pierwsza służy założeniu konta, druga tutaj logowaniu użytkownika i trzecia
dotyczy zwrócenia informacji na temat zalogowanego użytkownika.
Ta ostatnia będzie weryfikować nam token i
od teraz w przypadku samego logowania będziemy wykorzystywać dodatkową strategię
Passport umożliwiającą logowanie użytkownika.
W związku z tym mamy tutaj do czynienia z dwiema strategiami.
Pierwsze będzie polegało na tym, aby
wykorzystać dane logowania użytkownika podane razem z zapytaniem do tego, żeby
zweryfikować to, czy istnieje w bazie danych.
Jeżeli tak nie będzie, bądź też jego hasło
będzie niepoprawne, odrzucimy zapytanie, a w przeciwnym razie zwrócimy tutaj obiekt
użytkownika, który w tym przypadku zostanie dołączony do naszego obiektu
zapytania, tak jak pokazywałem to w poprzedniej lekcji.
Jeżeli chodzi o samą funkcję weryfikuj
obecność użytkownika, to w pierwszej kolejności wykorzystujemy jego login,
który powinien być dla każdego użytkownika unikatowy np.
adres email, a następnie w momencie gdy
sam użytkownik nie zostanie znaleziony zwracamy NULL.
Czyli tutaj warunek nie zostanie spełniony i połączenie zostanie odrzucone.
W przeciwnym razie użytkownik zostaje odnaleziony w bazie, więc musimy porównać
jego hasło z tym, które przechowywane jest w bazie.
Tak jak powiedziałem, z punktu widzenia
bezpieczeństwa w naszej bazie przechowywane są hash haseł.
Oznacza to, że nie możemy po prostu porównać wartości przesłanej przez
użytkownika, czyli po prostu jego hasła z wartością, którą przechowujemy w bazie.
Musimy w tym celu wykorzystać bibliotekę
Big Crypt oraz metodę Compare, aby porównać hash tych haseł.
No i tutaj mamy widzę tylko jeden mały
problem, ponieważ oczywiście w momencie gdy użytkownik nie zostanie znaleziony to
zwracamy wyjątek, a w przeciwnym razie weryfikujemy jego hasło i dopiero w
momencie, gdy to hasło jest poprawne, zwracamy informację na temat użytkownika.
W przeciwnym razie null.
Rezultat jest taki, że gdy login oraz hasło zgadzają się z tym, co mamy w bazie,
przechodzimy dalej i tym samym mamy dostęp do aplikacji.
W związku z tym powinniśmy wygenerować dla użytkownika token.
W tym przypadku po prostu szyfruje tzw.
palu, który zostanie zapisany w naszym token, a następnie z pomocą specjalnego
serwisu podpisujemy ten token i przesyłamy go do użytkownika.
Zwróć uwagę, że wewnątrz tokenu
uwzględniamy tylko informacje, które pozwolą nam zidentyfikować użytkownika.
Tak naprawdę nic nie stoi na przeszkodzie, abyśmy wykorzystali tutaj np.
wyłącznie jego identyfikator, ale w tym
momencie nic nie stoi na przeszkodzie, aby przesłać te dwie dane.
W każdym razie najważniejsze jest to, aby
wewnątrz tego pawilonu nie przechowywać żadnych danych wrażliwych, np.
adresu email.
Wynika to z faktu, że te informacje
wewnątrz tokenu mogą zostać w bardzo prosty sposób odczytane.
Zatem na tym etapie użytkownik powinien dostać swój access token.
Wróćmy jednak krok wcześniej do możliwości rejestrowania konta.
W tym przypadku użytkownik przesyła swój
login oraz hasło, a następnie wykorzystujemy tutaj BIG do tego, aby.
Hasz, który zostaje zapisany w bazie danych.
Jak widzisz, zapisujemy tutaj jego imię oraz hasło, a następnie zwracamy to, co
zostanie zwrócone przez tą metodę, czyli po prostu nowy obiekt użytkownika.
Myślę, że na tym etapie możemy przejść
tutaj przez proces tworzenia konta, czyli po prostu przesyłam tutaj dane użytkownika
i po utworzeniu tego konta jak widzisz zostaje tutaj wygenerowany jego obiekt
uwzględniający imię, hasło oraz identyfikator użytkownika.
Swoją drogą tak naprawdę w tym momencie
nie powinniśmy już przesyłać do klienta jego hasła.
Natomiast mi na tym zależało, aby było dla Ciebie jasne, że jego hasło nie zostaje
przechowywane w naszej bazie w formie bezpośredniej, czyli tzw.
plain tekstu.
W zamian przechowywany jest tutaj taki oto hash.
No i teraz, w momencie gdy mamy już konto
użytkownika, możemy się tutaj na nie zalogować.
W odpowiedzi otrzymujemy tutaj Access Token, którego ważność w konfiguracji
naszej aplikacji ustawiona jest na 60 sekund.
Zatem jeżeli skopiujesz sobie jego
zawartość, a następnie przekaże ją do kolejnego zapytania, wykorzystując tutaj
nagłówek, a następnie wartość, którą skopiowałem poprzedzoną frazą brr.
No to po wykonaniu tego zapytania otrzymam tutaj login użytkownika.
Wygląda na to, że wszystko się tutaj zgadza.
I teraz, w momencie gdy sam token albo
zostanie przesłany jako niepoprawny, to zablokuje nam się połączenie lub też
ewentualnie w momencie gdy przywrócimy ten token, ale jego wartość już wygasła.
Ze względu na to, że u mnie minęła już minuta i w związku z tym pomimo tego, że
mamy tutaj poprawny token, to nadal dostępu nie mamy.
I na tym etapie albo musimy zalogować się ponownie, aby uzyskać nowy token lub też
ewentualnie w momencie gdybyśmy mieli taki mechanizm zaimplementowany moglibyśmy
wykorzystać oddzielny endpoint do tego, aby przekazać tam refresh token i w zamian
odczytać nowy access token, który odblokuje nam dostęp do naszych zasobów.
I teraz tak w zasadzie mamy tutaj jeszcze nasz ostatni GET, który uwzględnia tak
naprawdę Password, który zajmuje się w całości tym, aby obsługiwać nasze tokeny.
Mamy tutaj zarówno nasz GET, jak i
strategię uwzględniającą to, aby odpowiednio obsłużyć same tokeny.
Jeżeli chodzi o szczegóły, myślę, że na
tym etapie nie będziemy się im bardzo przyglądać.
Natomiast jak widzisz mamy tutaj możliwość ustawienia tego, w jaki sposób odczytujemy
token i w naszym przypadku będzie to nagłówek.
Aczkolwiek na etapie tworzenia naszej aplikacji jest.
Wykorzystamy tutaj http only kuki.
Na razie jednak musisz wiedzieć, że
istnieje tutaj możliwość ustawienia kilku sposobów.
Następnie mamy możliwość weryfikowania wygaśnięcia tokenu.
Oczywiście ta opcja powinna być ustawiona na false, aczkolwiek np.
w środowisku deweloperskim możesz ustawić
tę wartość na true, oczywiście na podstawie zmiennych środowiskowych.
No i ostatecznie mamy jeszcze sekret,
który powinien być wygenerowany z pomocą następującej metody.
Mianowicie wykonuje polecenie,
aby udostępnić sobie możliwość wykonywania poleceń.
I tutaj wpisujesz następujące polecenie.
W rezultacie w momencie gdy je wykonasz, otrzymasz taki oto ciąg znaków, który
umieszczasz w pliku, a następnie wykorzystujesz w tym miejscu.
Oczywiście w tym wszystkim będziemy się
jeszcze zajmować, natomiast na ten moment nie ma co komplikować.
Najważniejsze jest dla mnie to, aby stało
się dla Ciebie jasne, że w momencie, gdy wykorzystujemy w 2.0 oraz tokeny jw.
Ważne jest to aby wykorzystać local
strategi do tego aby udostępnić logowanie użytkownika, ponieważ na tym etapie on
zgłasza się do nas aby uzyskać swój token, a następnie dopiero w momencie gdy będzie
prosił o jakieś dane, które wymagają uwierzytelnienia będziemy wykorzystywać go
uwzględniający właśnie przesłany przez niego token.
Dodatkowo jak widzisz mamy tutaj zastosowaną tą modyfikację obiektu
żądania, która dodaje obiekt użytkownika do tego żądania.
W rezultacie za każdym razem, gdy będziemy mieć podłączony ten gadżet, będziemy mieć
też dostęp do aktualnie zalogowanego użytkownika.
Wszystkie pozostałe elementy, które są tutaj uwzględnione, takie jak np.
połączenie z bazą danych, modele, serwisy itd.
Zostawimy sobie na później.
Podobnie też na później zostawimy sobie
sam mechanizm odświeżenia tokenów z pomocą Refresh token.
Zatem jeżeli chodzi o szybki przegląd tokenów j wt to by było na tyle, więc na
ten moment zachęcam Cię co najwyżej, aby przeklikać sobie zawartość tego projektu,
a następnie zapraszam Cię do kolejnej lekcji.