RESTful Authentication

745

Co oznacza uwierzytelnianie RESTful i jak działa? Nie mogę znaleźć dobrego przeglądu w Google. Rozumiem tylko, że przekazujesz klucz sesji (remeberal) w adresie URL, ale może to być strasznie złe.

Jim Keener
źródło
3
Kiedy google Restful Authentication znajduję kilkanaście wtyczek RoR. Zakładam, że NIE są tym, czego szukasz. Jeśli nie RoR, to w jakim języku? Jaki serwer WWW?
S.Lott,
2
Nie będzie strasznie źle, jeśli użyjesz HTTPS. Całe żądanie HTTP wraz z adresem URL zostanie zaszyfrowane.
Bharat Khatri
4
@BharatKhatri: Tak, tak. Nigdy nie przekazywałbym wrażliwych informacji w adresie URL widocznym dla użytkownika. Informacje te są bardziej prawdopodobne, że wyciekną ze względów praktycznych. HTTPS nie może pomóc w przypadku przypadkowego wycieku.
Jo So
2
@jcoffland: Co rozumiesz przez prawdziwe uwierzytelnianie RESTful? Jestem zainteresowany, ponieważ właśnie wdrożyłem trzeci sposób od zaakceptowanej odpowiedzi, jednak nie jestem z tego zadowolony (nie podoba mi się dodatkowy parametr w adresie URL).
BlueLettuce16
4
niektórzy ludzie używają jwt.io/introduction, aby rozwiązać ten problem. Obecnie badam ten problem, aby rozwiązać moją sprawę: stackoverflow.com/questions/36974163/... >> Mam nadzieję, że to zadziała dobrze.
toha

Odpowiedzi:

586

Sposób obsługi uwierzytelniania w architekturze RESTful klient-serwer jest kwestią dyskusyjną.

Zwykle można to osiągnąć w świecie SOA przez HTTP poprzez:

  • Podstawowe uwierzytelnianie HTTP przez HTTPS;
  • Pliki cookie i zarządzanie sesjami;
  • Token w nagłówkach HTTP (np. OAuth 2.0 + JWT);
  • Uwierzytelnianie zapytania z dodatkowymi parametrami podpisu.

Będziesz musiał dostosować lub nawet lepiej połączyć te techniki, aby najlepiej pasowały do ​​architektury oprogramowania.

Każdy schemat uwierzytelniania ma swoje PRO i CON, w zależności od celu Twojej polityki bezpieczeństwa i architektury oprogramowania.

Podstawowe uwierzytelnianie HTTP przez HTTPS

To pierwsze rozwiązanie, oparte na standardowym protokole HTTPS, jest używane przez większość usług internetowych.

GET /spec.html HTTP/1.1
Host: www.example.org
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

Jest łatwy do wdrożenia, domyślnie dostępny we wszystkich przeglądarkach, ale ma pewne znane wady, takie jak okropne okno uwierzytelniania wyświetlane w przeglądarce, które będzie się utrzymywać (nie ma tutaj funkcji podobnej do LogOut), dodatkowe zużycie procesora po stronie serwera, oraz fakt, że nazwa użytkownika i hasło są przesyłane (przez HTTPS) na serwer (powinno być bardziej bezpieczne, aby hasło pozostało tylko po stronie klienta, podczas wprowadzania klawiatury i było przechowywane jako bezpieczny skrót na serwerze) .

Możemy używać uwierzytelniania szyfrowanego , ale wymaga ono również HTTPS, ponieważ jest podatny na MiM lub Replay i jest specyficzny dla HTTP.

Sesja za pośrednictwem plików cookie

Szczerze mówiąc, sesja zarządzana na serwerze nie jest tak naprawdę bezstanowa.

Jedną z możliwości może być utrzymanie wszystkich danych w treści pliku cookie. Z założenia plik cookie jest obsługiwany po stronie serwera (klient w rzeczywistości nawet nie próbuje interpretować tych danych cookie: po prostu oddaje je z powrotem serwerowi przy każdym kolejnym żądaniu). Ale te pliki cookie są danymi stanu aplikacji, więc klient powinien nimi zarządzać, a nie serwer, w czystym świecie bezstanowym.

GET /spec.html HTTP/1.1
Host: www.example.org
Cookie: theme=light; sessionToken=abc123

Sama technika plików cookie jest połączona z HTTP, więc nie jest tak naprawdę RESTful, która powinna być niezależna od protokołu, IMHO. Jest podatny na MiM lub Replay .

Udzielone za pośrednictwem tokena (OAuth2)

Alternatywą jest umieszczenie tokena w nagłówkach HTTP, aby żądanie zostało uwierzytelnione. Tak działa na przykład OAuth 2.0. Zobacz RFC 6749 :

 GET /resource/1 HTTP/1.1
 Host: example.com
 Authorization: Bearer mF_9.B5f-4.1JqM

Krótko mówiąc, jest to bardzo podobne do pliku cookie i wiąże się z tymi samymi problemami: nie jest bezpaństwowcem, polega na szczegółach transmisji HTTP i podlega wielu niedociągnięciom w zakresie bezpieczeństwa - w tym MiM i Replay - więc należy go używać tylko przez HTTPS. Zazwyczaj JWT jest używany jako token.

Uwierzytelnianie zapytania

Uwierzytelnianie zapytania polega na podpisywaniu każdego żądania RESTful za pomocą dodatkowych parametrów w URI. Zobacz ten artykuł referencyjny .

Zostało to zdefiniowane w tym artykule:

Wszystkie zapytania REST muszą zostać uwierzytelnione poprzez podpisanie parametrów zapytania posortowanych małymi literami, w kolejności alfabetycznej, przy użyciu prywatnego poświadczenia jako tokena podpisującego. Podpisanie powinno nastąpić przed zakodowaniem ciągu zapytania w adresie URL.

Ta technika jest być może bardziej kompatybilna z architekturą bezstanową i może być również zaimplementowana z lekkim zarządzaniem sesjami (przy użyciu sesji w pamięci zamiast trwałości DB).

Na przykład, tutaj jest ogólna próbka URI z linku powyżej:

GET /object?apiKey=Qwerty2010

powinny być przekazywane jako takie:

GET /object?timestamp=1261496500&apiKey=Qwerty2010&signature=abcdef0123456789

Podpisywany ciąg to /object?apikey=Qwerty2010&timestamp=1261496500 a podpis jest skrótem SHA256 tego ciągu przy użyciu prywatnego komponentu klucza API.

Buforowanie danych po stronie serwera może być zawsze dostępne. Na przykład w naszej strukturze buforujemy odpowiedzi na poziomie SQL, a nie na poziomie identyfikatora URI. Tak więc dodanie tego dodatkowego parametru nie zrywa mechanizmu pamięci podręcznej.

Zobacz ten artykuł, aby uzyskać szczegółowe informacje na temat uwierzytelniania RESTful w naszej strukturze klient-serwer ORM / SOA / MVC w oparciu o JSON i REST. Ponieważ zezwalamy na komunikację nie tylko za pośrednictwem protokołu HTTP / 1.1, ale także nazwanych potoków lub komunikatów GDI (lokalnie), próbowaliśmy wdrożyć prawdziwie RESTfulowy wzór uwierzytelnienia, a nie polegać na specyficzności HTTP (takiej jak nagłówek lub pliki cookie).

Później Uwaga : dodanie podpisu do identyfikatora URI może być postrzegane jako zła praktyka (ponieważ na przykład pojawi się w logach serwera http), dlatego należy go złagodzić, np. Przez odpowiedni TTL, aby uniknąć powtórek. Ale jeśli Twoje dzienniki HTTP zostaną naruszone, na pewno będziesz mieć większe problemy z bezpieczeństwem.

W praktyce nadchodzące uwierzytelnianie tokenów MAC dla OAuth 2.0 może być ogromną poprawą w stosunku do obecnego schematu „Przyznany przez token”. Ale to wciąż jest w toku i jest związane z transmisją HTTP.

Wniosek

Warto stwierdzić, że REST jest oparty nie tylko na HTTP, nawet jeśli w praktyce jest on głównie implementowany przez HTTP. REST może korzystać z innych warstw komunikacyjnych. Tak więc uwierzytelnianie RESTful to nie tylko synonim uwierzytelniania HTTP, niezależnie od odpowiedzi Google. Nie powinien nawet w ogóle korzystać z mechanizmu HTTP, ale powinien zostać wyodrębniony z warstwy komunikacyjnej. A jeśli korzystasz z komunikacji HTTP, dzięki inicjatywie Let's Encrypt nie ma powodu, aby nie używać właściwego protokołu HTTPS, który jest wymagany oprócz jakiegokolwiek schematu uwierzytelniania.

Arnaud Bouchez
źródło
5
Jeśli użyjesz go Cookiejako lepszego zamiennika HTTP Basic Auth, możesz zrobić autentyczne bezpaństwowe uwierzytelnianie z metodą wygasania uwierzytelnienia i możliwością wylogowania. W przykładowej implementacji można użyć pliku cookie Emulated-HTTP-Basic-Autho podobnej wartości do rzeczywistego uwierzytelniania podstawowego HTTP, a ponadto ustawić czas wygaśnięcia. Następnie można wylogować się poprzez usunięcie tego pliku cookie. Sądzę, że każdy klient obsługujący uwierzytelnianie podstawowe HTTP może również obsługiwać uwierzytelnianie plików cookie w ten sposób.
Mikko Rantalainen,
4
@MikkoRantalainen Ale, jak napisałem, ten plik cookie nadal będzie zarządzany przez serwer. Jest to jakiś rodzaj bezpaństwowca, ale nie „czysty” bezpaństwowiec. We wszystkich przypadkach potrzebny jest kod JavaScript dedykowany do logowania / wylogowania klienta, co jest całkowicie możliwe, np. Dzięki HTTP Digest Auth - dobry pomysł, ale tutaj nie ma dużej korzyści, aby wynaleźć koło na nowo.
Arnaud Bouchez
4
Twierdziłbym, że serwer implementuje interfejs użytkownika i logikę do konfigurowania nagłówka, ale sam nagłówek jest bezstanowy. Klient zaprojektowany dla interfejsu API może pominąć korzystanie z pomocy serwera do skonfigurowania nagłówka i po prostu przekazać wymagane informacje podobne do HTTP Basic Auth. Chodzi mi o to, że popularne UA (przeglądarki) mają tak słabą implementację Podstawowego uwierzytelniania, że ​​nie można z nich korzystać. CookieZamiast tego można użyć emulacji serwera dla tych samych elementów w innym nagłówku ( ).
Mikko Rantalainen
6
Chyba poprawną odpowiedzią jest stackoverflow.com/questions/6068113/…
graffic
7
Brzydkie hasło do autoryzacji HTTP pojawi się tylko wtedy, gdy serwer zażąda go poprzez odesłanie nieautoryzowanej odpowiedzi 401. Jeśli Ci się nie podoba, po prostu wyślij 403 Forbidden. Strona błędu może zawierać metodę logowania lub link do niej. Jednak największym argumentem przeciwko plikom cookie ORAZ uwierzytelnianiu HTTP (niezależnie od tego, czy stan jest po stronie serwera, czy po stronie klienta) jest to, że są one podatne na fałszowanie żądań między witrynami. Z tego powodu najlepszym podejściem jest niestandardowy schemat autoryzacji, niestandardowy nagłówek autoryzacji lub niestandardowy parametr GET lub POST.
Dobes Vandermeer
418

Wątpię, czy ludzie entuzjastycznie krzyczący „Uwierzytelnianie HTTP” kiedykolwiek próbowali stworzyć aplikację opartą na przeglądarce (zamiast usługi sieciowej maszyna-maszyna) z REST (bez przestępstwa - nie sądzę, żeby kiedykolwiek napotkali komplikacje) .

Problemy, które znalazłem przy użyciu uwierzytelniania HTTP w usługach RESTful, które produkują strony HTML do przeglądania w przeglądarce to:

  • użytkownik zazwyczaj otrzymuje brzydkie okno logowania, które jest bardzo nieprzyjazne dla użytkownika. nie można dodawać pobierania hasła, pól pomocy itp.
  • Wylogowanie lub zalogowanie się pod inną nazwą stanowi problem - przeglądarki będą wysyłać informacje uwierzytelniające do witryny, dopóki nie zamkniesz okna
  • limity czasu są trudne

Bardzo wnikliwy artykuł, który porusza te kwestie punkt po punkcie, znajduje się tutaj , ale powoduje to wiele hackerów związanych z przeglądarką javascript, obejścia obejść i tak dalej. Jako taki nie jest również zgodny z poprzednimi wersjami, dlatego będzie wymagał ciągłej konserwacji w miarę wydawania nowych przeglądarek. Nie uważam tego za czysty i przejrzysty projekt, a ponadto uważam, że jest to dużo dodatkowej pracy i bólu głowy, po to, abym mógł z entuzjazmem pokazać moją odznakę REST moim znajomym.

Wierzę, że pliki cookie są rozwiązaniem. Ale czekaj, ciasteczka są złe, prawda? Nie, nie są, sposób, w jaki często wykorzystywane są pliki cookie, jest zły. Sam plik cookie to tylko część informacji po stronie klienta, podobnie jak informacje o uwierzytelnieniu HTTP, które przeglądarka śledziłaby podczas przeglądania. I ta część informacji po stronie klienta jest wysyłana do serwera na każde żądanie, podobnie jak informacje o uwierzytelnianiu HTTP. Koncepcyjnie jedyną różnicą jest to, że zawartość tego elementu stanu po stronie klienta może być określona przez serwer jako część jego odpowiedzi.

Dzięki uczynieniu sesji zasobem RESTful opartym tylko na następujących zasadach:

  • Sesji mapuje klucz do ID użytkownika (i ewentualnie w ostatniej akcji znacznik czasu dla limitu czasu)
  • Jeśli sesja istnieje, oznacza to, że klucz jest prawidłowy.
  • Logowanie oznacza wysyłanie do / sesji, nowy klucz jest ustawiony jako ciasteczko
  • Wylogowanie oznacza USUŃ / sesje / {klucz} (przy przeciążonym POST, pamiętaj, że jesteśmy przeglądarką, a HTML 5 to jeszcze długa droga)
  • Uwierzytelnianie odbywa się poprzez wysłanie klucza jako pliku cookie na każde żądanie i sprawdzenie, czy sesja istnieje i jest ważna

Jedyną różnicą w stosunku do uwierzytelniania HTTP jest teraz to, że klucz uwierzytelniający jest generowany przez serwer i wysyłany do klienta, który wysyła go z powrotem, zamiast klienta obliczającego go na podstawie wprowadzonych poświadczeń.

Konwerter42 dodaje, że podczas korzystania z protokołu https (co powinniśmy zrobić) ważne jest, aby plik cookie miał ustawioną bezpieczną flagę, aby informacje o uwierzytelnieniu nigdy nie były wysyłane przez niezabezpieczone połączenie. Świetny punkt, sam tego nie widziałem.

Wydaje mi się, że jest to wystarczające rozwiązanie, które działa dobrze, ale muszę przyznać, że nie jestem wystarczającym ekspertem ds. Bezpieczeństwa, aby zidentyfikować potencjalne dziury w tym schemacie - wiem tylko, że setki aplikacji internetowych innych niż RESTful używają zasadniczo tego samego protokół logowania ($ _SESSION w PHP, HttpSession w Java EE itp.). Zawartość nagłówka pliku cookie jest po prostu używana do adresowania zasobu po stronie serwera, podobnie jak język akceptacji może być używany do uzyskiwania dostępu do zasobów tłumaczeń itp. Czuję, że jest tak samo, ale może inni nie? Co myślicie, chłopaki?

skrebbel
źródło
68
Jest to pragmatyczna odpowiedź i proponowane rozwiązanie działa. Jednak użycie terminów „RESTful” i „sesja” w tym samym zdaniu jest po prostu niepoprawne (chyba że pomiędzy nimi występuje również „nie”;). Innymi słowy: każda usługa sieciowa, która korzysta z sesji, NIE jest RESTOWANA (z definicji). Nie zrozum mnie źle - nadal możesz używać tego rozwiązania (YMMV), ale nie można do niego użyć terminu „RESTful”. Polecam książkę O'Reilly na temat REST, która jest bardzo czytelna i wyjaśnia szczegółowo temat.
johndodo
23
@skrebbel: czyste rozwiązanie REST wysyła dane uwierzytelniające za każdym razem, gdy żąda zasobu, który jest mniej niż doskonały (HTTP Auth to robi). Proponowane rozwiązanie działa i jest lepsze w większości przypadków użycia, ale nie jest RESTful. Nie ma potrzeby wojny, ja też używam tego rozwiązania. Po prostu nie twierdzę, że to jest ODPOCZNE. :)
johndodo
94
Och, daj spokój, podaj przykład. Jaki jest inny sposób, który działa dobrze? Naprawdę chciałbym wiedzieć. HTTP Auth z pewnością nie jest, nie można się wylogować bez zamykania przeglądarki i nie można zaoferować przyzwoitego logowania bez wielu JS, które nie są kompatybilne z przeglądarkami. Nie dbam tak bardzo o „czysto RESTful” vs. „prawie RESTful” i całą związaną z tym debatę religijną, ale jeśli powiesz, że istnieje kilka sposobów, powinieneś je przeliterować.
skrebbel
15
Prawdziwie RESTful autentykacja za pomocą rzeczywistych programów użytkownika (zwanych także „przeglądarkami”) składa się z pliku cookie zawierającego wartość uwierzytelnienia HTTP. W ten sposób serwer może dostarczyć interfejs użytkownika do wprowadzania loginu i hasła, a serwer może wymusić wylogowanie (poprzez usunięcie pliku cookie). Ponadto zamiast odpowiadać 401 na żądanie logowania w przypadku niepowodzenia uwierzytelnienia, serwer musi użyć tymczasowego przekierowania do ekranu logowania, a po udanym logowaniu użyć tymczasowego przekierowania z powrotem do poprzedniej lokalizacji. Ponadto serwer musi osadzić akcję wylogowania (formularz POST) na prawie każdej stronie dla zalogowanych użytkowników.
Mikko Rantalainen
15
Nie widzę nic złego w używaniu słów „spokojny” i „sesyjny” w tym samym zdaniu, o ile jasne jest, że sesja istnieje tylko po stronie klienta. Nie jestem pewien, dlaczego tak ważna jest kwestia tej koncepcji.
Joe Phillips
140

Dość już powiedzieli na ten temat dobrzy ludzie tutaj. Ale oto moje 2 centy.

Istnieją 2 tryby interakcji:

  1. człowiek-maszyna (HTM)
  2. maszyna do maszyny (MTM)

Maszyna jest wspólnym mianownikiem, wyrażonym jako interfejsy API REST, a aktorami / klientami są ludzie lub maszyny.

Teraz, w architekturze naprawdę RESTful, koncepcja bezpaństwowości oznacza, że ​​wszystkie odpowiednie stany aplikacji (czyli stany po stronie klienta) muszą być dostarczane z każdym żądaniem. Przez odpowiednie rozumie się, że wszystko, co jest wymagane przez interfejs API REST do przetworzenia żądania i dostarczenia odpowiedniej odpowiedzi.

Gdy weźmiemy to pod uwagę w kontekście aplikacji typu człowiek-maszyna, „opartych na przeglądarce”, jak wskazał powyżej Skrebbel, oznacza to, że aplikacja (internetowa) działająca w przeglądarce będzie musiała wysyłać swój stan i odpowiednie informacje przy każdym żądaniu sprawia, że ​​do interfejsów API REST zaplecza.

Rozważ to: masz udostępniony przez platformę danych / informacji zasób interfejsów API REST. Być może masz samoobsługową platformę BI, która obsługuje wszystkie kostki danych. Ale chcesz, aby Twoi (ludzcy) klienci mieli do niej dostęp za pośrednictwem (1) aplikacji internetowej, (2) aplikacji mobilnej i (3) aplikacji innej firmy. W końcu nawet łańcuch MTM prowadzi do HTM - prawda. Tak więc użytkownicy pozostają na szczycie łańcucha informacyjnego.

W pierwszych 2 przypadkach masz przypadek interakcji człowieka z maszyną, przy czym informacje są faktycznie konsumowane przez użytkownika. W ostatnim przypadku masz program komputerowy korzystający z interfejsów API REST.

Koncepcja uwierzytelnienia obowiązuje na całym forum. Jak to zaprojektujesz, aby uzyskać dostęp do interfejsów API REST w jednolity, bezpieczny sposób? Widzę to na dwa sposoby:

Sposób 1:

  1. Na początek nie ma loginu. Każde żądanie wykonuje logowanie
  2. Klient przesyła swoje parametry identyfikacyjne + parametry specyficzne dla żądania przy każdym żądaniu
  3. Interfejs API REST bierze je, odwraca, wysyła ping do sklepu użytkownika (cokolwiek to jest) i potwierdza autoryzację
  4. Jeśli autoryzacja została ustanowiona, obsługuje żądanie; w przeciwnym razie zaprzecza odpowiednim kodem stanu HTTP
  5. Powtórz powyższe dla każdego żądania we wszystkich interfejsach API REST w Twoim katalogu

Sposób 2:

  1. Klient rozpoczyna się od żądania autoryzacji
  2. Interfejs API REST logowania obsługuje wszystkie takie żądania
  3. Pobiera parametry uwierzytelniania (klucz API, uid / pwd lub cokolwiek innego) i weryfikuje uwierzytelnianie względem magazynu użytkowników (LDAP, AD lub MySQL DB itp.)
  4. Jeśli zostanie zweryfikowany, tworzy token uwierzytelnienia i przekazuje go klientowi / rozmówcy
  5. Osoba dzwoniąca wysyła następnie ten token uwierzytelniania + określone parametry z każdym kolejnym żądaniem do innych biznesowych interfejsów API REST, do czasu wylogowania lub wygaśnięcia dzierżawy

Oczywiście w Way-2 interfejsy API REST będą potrzebowały sposobu na rozpoznanie i zaufanie tokena jako ważnego. Interfejs API logowania wykonał weryfikację uwierzytelnienia, dlatego też „kluczowi samochodu” muszą zaufać inne interfejsy API REST w katalogu.

To oczywiście oznacza, że ​​klucz / token uwierzytelniania będzie musiał być przechowywany i udostępniany interfejsom API REST. To współużytkowane, zaufane repozytorium tokenów może być lokalne / stowarzyszone, co pozwala interfejsom API REST innych organizacji na wzajemne zaufanie.

Ale dygresję.

Chodzi o to, że „stan” (o statusie uwierzytelnienia klienta) musi być utrzymywany i udostępniany, aby wszystkie interfejsy API REST mogły utworzyć krąg zaufania. Jeśli tego nie zrobimy, czyli Way-1, musimy zaakceptować fakt, że dla każdego przychodzącego żądania należy wykonać czynność uwierzytelnienia.

Przeprowadzanie uwierzytelnienia jest procesem wymagającym dużych zasobów. Wyobraź sobie wykonywanie zapytań SQL dla każdego przychodzącego żądania względem sklepu użytkownika w celu sprawdzenia zgodności uid / pwd. Lub do szyfrowania i wykonywania dopasowań skrótów (styl AWS). Pod względem architektonicznym każdy interfejs API REST będzie musiał to zrobić, podejrzewam, za pomocą wspólnej usługi logowania zaplecza. Ponieważ jeśli nie, to zaśmiecasz wszędzie kod uwierzytelniający. Wielki bałagan.

Więcej warstw, więcej opóźnień.

Teraz weź Way-1 i złóż wniosek do HTM. Czy Twój (ludzki) użytkownik naprawdę dba o to, czy musisz wysyłać identyfikator UID / PWD / HASH lub cokolwiek innego przy każdym żądaniu? Nie, dopóki nie przeszkadzasz jej, rzucając stronę uwierzytelniania / logowania co sekundę. Powodzenia, jeśli masz klientów. Tak więc, na początku, będziesz przechowywać dane logowania gdzieś po stronie klienta, w przeglądarce, i wysyłać je przy każdym zgłoszonym żądaniu. Dla użytkownika (ludzkiego) już się zalogowała i dostępna jest „sesja”. Ale w rzeczywistości jest uwierzytelniana na każde żądanie.

To samo z Way-2. Twój (ludzki) użytkownik nigdy tego nie zauważy. Więc nie wyrządzono żadnej krzywdy.

Co jeśli zastosujemy Way-1 do MTM? W tym przypadku, ponieważ jest to maszyna, możemy nudzić tego faceta, prosząc go o przesyłanie informacji uwierzytelniających przy każdym żądaniu. Nikogo to nie obchodzi! Wykonanie Way-2 na MTM nie wywoła żadnej specjalnej reakcji; to cholerna maszyna. To może mniej obchodzić!

Tak naprawdę pytanie dotyczy tego, co odpowiada Twoim potrzebom. Bezpaństwowość ma swoją cenę. Zapłać cenę i idź dalej. Jeśli chcesz być purystą, zapłać za to cenę i idź dalej.

W końcu filozofie nie mają znaczenia. Najważniejsze jest odkrywanie informacji, prezentacja i wrażenia konsumpcyjne. Jeśli ludzie uwielbiają twoje interfejsy API, wykonałeś swoją pracę.

Kingz
źródło
3
Proszę pana, wyjaśniłeś to tak pięknie, że mam jasne pojęcie o podstawowej kwestii / pytaniu. Jesteś jak Budda! Mogę dodać, że używając HTTPS w warstwie transportowej, możemy nawet zapobiec atakom Man In the Middle, aby nikt nie przejął mojego klucza identyfikacyjnego (jeśli wybrano Way-1)
Vishnoo Rath
Czy nie zawsze urządzenie wykonuje uwierzytelnianie? Człowiek nie drażni się z hasłami, jest to niefortunna irytacja dla użytkowników, którzy poprawnie racjonalizują bezpieczeństwo. Dla mnie problemem programisty jest to, jak chcą, aby maszyna wykonała swoją pracę.
Todd Baur
9
Czytam twoją odpowiedź; w twoim rozwiązaniu, za każde pojedyncze żądanie internetowe pochodzące z przeglądarki przez kliknięcia użytkownika, będziesz musiał odesłać „token autoryzacji” z powrotem do dowolnego interfejsu API, który wywołuje kliknięcie użytkownika. Co wtedy? Interfejs API wykonuje sprawdzenie tokena. Przeciwko czemu? Przeciw pewnego rodzaju „magazynowi tokenów”, który utrzymuje, czy ten token jest ważny, czy nie. Czy nie zgadzasz się, że ten „sklep z tokenami” staje się wówczas posiadaczem „państwa”? Naprawdę, jakkolwiek to widzisz, ktoś gdzieś musi wiedzieć coś o „tokenach” przekazywanych na działania użytkownika. Tam mieszkają informacje o stanie.
Kingz
5
A przez usługę „bezstanowy” rozumie się tak naprawdę to, że ten konkretny składnik serwera (interfejsy API CRUD) nie przenosi żadnych stanów. Nie rozpoznają jednego użytkownika od drugiego i wypełniają żądanie użytkownika w całości w ramach jednej transakcji. To jest bezpaństwowość. Ale ktoś gdzieś musi siedzieć i oceniać, czy ten użytkownik jest ważny, czy nie. Nie ma innego sposobu, aby to zrobić; klucze lub hasła lub cokolwiek innego. Wszelkie informacje przekazywane po stronie użytkownika muszą zostać uwierzytelnione i autoryzowane.
Kingz
1
Tęsknisz Way-3za podejściem hybrydowym. Klient loguje się jak w, Way-2ale, podobnie jak w Way-1, poświadczenia nie są sprawdzane względem żadnego stanu po stronie serwera. Niezależnie od tego token uwierzytelniający jest tworzony i wysyłany z powrotem do klienta, jak w Way-2. Ten token jest później sprawdzany pod kątem autentyczności za pomocą asymetrycznego szyfrowania bez wyszukiwania dowolnego stanu określonego klienta.
jcoffland,
50

Oto prawdziwie i całkowicie RESTful rozwiązanie uwierzytelniające:

  1. Utwórz parę kluczy publiczny / prywatny na serwerze uwierzytelniania.
  2. Rozdaj klucz publiczny wszystkim serwerom.
  3. Gdy klient uwierzytelnia się:

    3.1 wystawić token, który zawiera:

    • Data ważności
    • nazwa użytkownika (opcjonalnie)
    • IP użytkowników (opcjonalnie)
    • skrót hasła (opcjonalnie)

    3.2 Zaszyfruj token kluczem prywatnym.

    3.3 Wyślij zaszyfrowany token z powrotem do użytkownika.

  4. Gdy użytkownik uzyskuje dostęp do dowolnego interfejsu API, musi również przekazać swój token uwierzytelniania.

  5. Serwery mogą sprawdzić, czy token jest prawidłowy, odszyfrowując go za pomocą klucza publicznego serwera autoryzacji.

Jest to uwierzytelnianie bezstanowe / RESTful.

Zauważ, że jeśli zostanie dołączony skrót hasła, użytkownik wyśle ​​również niezaszyfrowane hasło wraz z tokenem uwierzytelniającym. Serwer może sprawdzić, czy hasło jest zgodne z hasłem użytym do utworzenia tokena uwierzytelniającego, porównując skróty. Konieczne byłoby bezpieczne połączenie przy użyciu czegoś takiego jak HTTPS. JavaScript po stronie klienta może obsłużyć pobieranie hasła użytkownika i przechowywanie go po stronie klienta, w pamięci lub w pliku cookie, prawdopodobnie zaszyfrowanym kluczem publicznym serwera .

jcoffland
źródło
5
Co się stanie, jeśli ktoś zdobędzie ten token uwierzytelniania i wywoła z nim interfejsy API, podszywając się pod klienta?
Abidi
2
@Abidi, tak, to jest problem. Możesz wymagać hasła. Hash hasła może być zawarty w tokenie uwierzytelniającym. Gdyby ktoś był w stanie ukraść token, byłby podatny na ataki siłowe offline. Gdyby wybrano silne hasło, nie byłoby problemu. Zauważ, że jeśli używałeś kradzieży tokenu https, atakujący musiałby najpierw uzyskać dostęp do komputera klienta.
jcoffland
1
Ponieważ tylko serwer uwierzytelniający zna klucz prywatny. Inne serwery mogą uwierzytelniać użytkownika, znając jedynie klucz publiczny i token użytkownika.
jcoffland
1
Asymetryczne szyfrowanie i deszyfrowanie jest o rząd wielkości wolniejsze (bardziej wymagające obliczeniowo) niż szyfrowanie symetryczne. Posługiwanie się serwerem za pomocą klucza publicznego do odszyfrowywania tokena przy każdym połączeniu byłby ogromnym wąskim gardłem wydajności.
Craig
3
@ jcoffland naprawdę promowałeś swoją odpowiedź tutaj (wielokrotnie :-) Ale nie mogę przestać komentować problemów z wydajnością (intensywność obliczeń) korzystania z szyfrowania asymetrycznego przy każdym połączeniu. Po prostu nie widzę rozwiązania, które ma taką zdolność do skalowania. Wyszukaj protokół HTTPS i SPDY. Dokłada wszelkich starań, aby utrzymywać otwarte połączenia (HTTP utrzymywać przy życiu, co jest stanem) i obsługiwać wiele zasobów w partiach przez to samo połączenie (więcej stanów), i oczywiście sam SSL używa tylko szyfrowania asymetrycznego do wymiany symetrycznego klucza szyfrującego ( również stan).
Craig
37

Szczerze mówiąc, widziałem tu świetne odpowiedzi, ale coś mnie niepokoi, gdy ktoś doprowadzi całą koncepcję bezpaństwowości do skrajności, gdy staje się dogmatyczna. Przypomina mi tych starych fanów Smalltalk, którzy chcieli tylko zaakceptować czysty OO, a jeśli coś nie jest przedmiotem, robisz to źle. Daj mi spokój.

RESTful podejście ma ułatwić Ci życie i zmniejszyć koszty ogólne i koszty sesji, staraj się postępować zgodnie z nim, ponieważ jest to mądre, ale w momencie, gdy podążasz za dyscypliną (dowolną dyscypliną / wytyczną) aż do skrajności nie zapewnia już korzyści, dla której był przeznaczony, wtedy robisz to źle. Niektóre z najlepszych obecnie języków mają zarówno funkcjonalne programowanie, jak i orientację obiektową.

Jeśli najłatwiejszym sposobem rozwiązania problemu jest przechowanie klucza uwierzytelniającego w pliku cookie i wysłanie go w nagłówku HTTP, zrób to, po prostu go nie nadużywaj. Pamiętaj, że sesje są złe, gdy stają się ciężkie i duże, jeśli cała sesja składa się z krótkiego ciągu zawierającego klucz, to o co chodzi?

Jestem otwarty na akceptację poprawek w komentarzach, ale po prostu nie widzę sensu (jak dotąd) powodowania, że ​​nasze życie jest nieszczęśliwe, aby po prostu uniknąć przechowywania dużego słownika skrótów na naszym serwerze.

arg20
źródło
2
Ludzie nie próbują zabronić ci korzystania z sesji. Możesz to zrobić. Ale jeśli to zrobisz, nie będzie to REST.
André Caldas,
6
@ AndréCaldas to nie jest REST w taki sam sposób, w jaki posiadanie funkcji lub typów pierwotnych w języku nie jest przerywane. Nie twierdzę, że sesje są wskazane. Po prostu wyrażam swoją opinię na temat stosowania zestawu praktyk w zakresie, w jakim nie zapewniają już komuś korzyści. (Przy okazji, zauważ, że nie sprzeciwiłem się twoim uwagom, jednak nie powiedziałbym, że to nie jest REST, powiedziałbym, że to nie jest czysty REST).
arg20
Jak to nazwiemy, jeśli nie jest to ODPOCZYNEK? I na pewno, jeśli żądanie zawiera identyfikator sesji, to jest ono tak samo bezstanowe jak żądanie zawierające identyfikator użytkownika? Dlaczego identyfikator użytkownika jest bezstanowy, a identyfikator sesji stanowy?
mfhholmes
1
Pliki cookie są podatne na fałszowanie żądań w różnych witrynach, dlatego ułatwiają naruszanie bezpieczeństwa. Lepiej użyć czegoś, co nie jest automatycznie wysyłane przez przeglądarkę, takiego jak niestandardowy nagłówek lub niestandardowy schemat autoryzacji.
Dobes Vandermeer
1
W rzeczywistości próba bycia bezpaństwowcem nie polega na dogmatyzmie, ale na jednej wspólnej koncepcji samego SOA. Usługi powinny zawsze czerpać korzyści z braku powiązania i bezpaństwowości: w praktyce ułatwia skalowanie, dostępność i łatwość konserwacji. Oczywiście powinno być tak dużo, jak to możliwe, i w końcu potrzebowałbyś „usług orkiestracyjnych”, aby zarządzać tymi bezpaństwowymi usługami w sposób stanowczy i pragmatyczny.
Arnaud Bouchez
32

Przede wszystkim usługa sieci web RESTful jest BEZ STATELERA (lub innymi słowy SESSIONLESS). Dlatego usługa RESTful nie ma i nie powinna obejmować koncepcji sesji ani plików cookie. Sposobem na uwierzytelnienie lub autoryzację w usłudze RESTful jest użycie nagłówka autoryzacji HTTP zgodnie ze specyfikacją HTTP RFC 2616. Każde pojedyncze żądanie powinno zawierać nagłówek autoryzacji HTTP, a żądanie powinno zostać wysłane przez połączenie HTTPs (SSL). Jest to poprawny sposób na uwierzytelnianie i weryfikację autoryzacji żądań w usługach WWW HTTP RESTful. Wdrożyłem usługę internetową RESTful dla aplikacji Cisco PRIME Performance Manager w Cisco Systems. W ramach tej usługi sieciowej zaimplementowałem również uwierzytelnianie / autoryzację.

rubens
źródło
5
Uwierzytelnianie HTTP nadal wymaga od serwera śledzenia identyfikatorów użytkowników i haseł. To nie jest całkowicie bezpaństwowiec.
jcoffland
21
Jest bezstanowy w tym sensie, że każde żądanie jest poprawne samo, bez żadnych wymagań poprzednich wniosków. Sposób implementacji na serwerze to inna sprawa, jeśli uwierzytelnianie jest drogie, możesz wykonać buforowanie i ponownie uwierzytelnić się w przypadku braku pamięci podręcznej. Bardzo niewiele serwerów jest całkowicie bezstanowych, a dane wyjściowe są wyłącznie funkcją danych wejściowych. Zazwyczaj jest to zapytanie lub aktualizacja do jakiegoś stanu.
Erik Martino
3
Nie prawda. W takim przypadku wszystkie żądania wymagają stanu z poprzedniej transakcji, a mianowicie rejestracji użytkownika. Nie rozumiem, dlaczego ludzie próbują powiedzieć, że nazwa użytkownika i hasło przechowywane na serwerze nie są stanem po stronie serwera. Zobacz moją odpowiedź.
jcoffland
1
@jcoffland Ponadto, twoje rozwiązanie w dużej mierze opiera się na zdolności serwera API do odszyfrowania podpisanego tokena. Myślę, że to podejście jest nie tylko zbyt szczegółowe, ale także nieco zbyt wyrafinowane, aby myśleć o nim jako o podejściu R. Fieldinga, który miał na celu rozwiązanie problemu uwierzytelnienia RESTful.
Michael Ekoka
2
@ jcoffland, czy rozumiesz, jak głęboko asymetryczne jest szyfrowanie o dużej intensywności obliczeniowej (a co za tym idzie o dużym zużyciu zasobów i bardzo powolnym)? Mówisz o schemacie, który wykorzystuje szyfrowanie asymetryczne przy każdym żądaniu. Najwolniejszym aspektem HTTPS, bez żadnych przeszkód, jest początkowy uścisk dłoni, który polega na utworzeniu kluczy publicznych / prywatnych w celu asymetrycznego szyfrowania wspólnego hasła, które jest następnie wykorzystywane do symetrycznego szyfrowania całej późniejszej komunikacji.
Craig,
22

Z pewnością nie chodzi o „klucze sesji”, ponieważ jest ogólnie używany w odniesieniu do uwierzytelniania bez sesji, które jest wykonywane we wszystkich ograniczeniach REST. Każde żądanie jest samoopisujące i zawiera wystarczającą ilość informacji, aby samodzielnie je autoryzować bez żadnego stanu aplikacji po stronie serwera.

Najprościej jest to zrobić, zaczynając od wbudowanych mechanizmów uwierzytelniania HTTP w RFC 2617 .

Justin Sheehy
źródło
Uwierzytelnianie HTTP wymaga od serwera przechowywania nazwy użytkownika i hasła. Jest to stan po stronie serwera i dlatego nie jest ściśle REST. Zobacz moją odpowiedź.
jcoffland
3
@jcoffland: To po prostu nieprawda, na obu kontach. Pierwsze uwierzytelnianie HTTP nie wymaga od serwera przechowywania hasła. Hash z hasła są przechowywane zamiast (bcrypt z 8+ rund zalecane). Po drugie, serwer nie ma żadnego stanu, ponieważ nagłówek autoryzacji jest wysyłany przy każdym żądaniu. A jeśli uznasz, że hash przechowywane hasła są stanem , nie są one bardziej niż stanem przechowywanych kluczy publicznych.
Boris B.
1
@ Boris B., tak Rozumiem, że hasło jest przechowywane jako skrót. Zaszyfrowane hasło jest nadal specyficzne dla klienta. Różnica w przechowywaniu klucza publicznego, jak opisano w moim rozwiązaniu, polega na tym, że istnieje tylko jeden klucz publiczny, klucz publiczny serwera uwierzytelniającego. To bardzo różni się od przechowywania skrótu hasła dla użytkownika. Bez względu na to, jak je ubierzesz, jeśli serwer przechowuje hasło dla każdego użytkownika, jest ono zapisywane według stanu użytkownika i nie jest w 100% REST.
jcoffland
7
Nie sądzę, aby przechowywanie hasła użytkownika zakodowanego na serwerze powinno być uważane za stan po stronie serwera. Użytkownicy to zasoby zawierające informacje, takie jak imię i nazwisko, adres lub zaszyfrowane hasło.
Codepunkt
15

„Bardzo wnikliwy” artykuł wspomniany przez @skrebel ( http://www.berenddeboer.net/rest/authentication.html ) omawia skomplikowaną, ale naprawdę zepsutą metodę uwierzytelniania.

Możesz spróbować odwiedzić stronę (która ma być widoczna tylko dla uwierzytelnionego użytkownika) http://www.berenddeboer.net/rest/site/authenticated.html bez żadnych danych logowania.

(Przepraszam, nie mogę skomentować odpowiedzi.)

Powiedziałbym, że REST i uwierzytelnianie po prostu się nie łączą. REST oznacza bezstanowy, ale „uwierzytelniony” jest stanem. Nie możesz mieć ich obu na tej samej warstwie. Jeśli jesteś zwolennikiem ODPOWIEDZIALNYM i marszczysz brwi na punkcie stanów, musisz przejść do HTTPS (tzn. Zostawić kwestię bezpieczeństwa na innej warstwie).

Ji Han
źródło
Stripe.com powiedziałby inaczej w swoim komentarzu na temat REST i uwierzytelnienia, które nie mieszają się.
Erik
Bezstanowy odnosi się tylko do serwera, a nie do klienta. Klient może zapamiętać cały stan sesji i wysłać to, co jest istotne dla każdego żądania.
Dobes Vandermeer
Wreszcie ktoś mówi w pewnym sensie, ale uwierzytelnianie bezstanowe jest możliwe przy użyciu szyfrowania z kluczem publicznym. Zobacz moją odpowiedź.
jcoffland
1
Serwer nie ma stanu „uwierzytelnionego”. Otrzymuje informacje za pośrednictwem hipermediów i musi z nimi współpracować, aby zwrócić to, czego zażądano. Nic mniej, nic więcej. Jeśli zasób jest chroniony i wymaga uwierzytelnienia i autoryzacji, dostarczona hipermedia musi zawierać te informacje. Nie wiem, skąd pochodzi pojęcie, że uwierzytelnianie użytkownika przed zwróceniem zasobu oznacza, że ​​serwer śledzi stan. Podanie nazwy użytkownika i hasła można uznać za po prostu zapewnienie większej liczby parametrów filtrowania.
Michael Ekoka
„Powiedziałbym, że REST i uwierzytelnianie po prostu się nie łączą”. Brzmi jak zdrowy rozsądek. Tyle, że system niezgodny z uwierzytelnianiem (sam „uwierzytelniony” jest oczywiście stanem) ma ograniczoną użyteczność. Wydaje mi się, że wszyscy kłócimy się na pograniczu praktyczności i purystycznego dogmatyzmu, i szczerze mówiąc praktyczność powinna wygrać. Istnieje wiele aspektów REST, które są bardzo korzystne bez wchodzenia w zniekształcenia próbujące uniknąć stanu w odniesieniu do uwierzytelniania, prawda?
Craig,
12

Myślę, że spokojne uwierzytelnianie obejmuje przekazanie tokena uwierzytelniającego jako parametru w żądaniu. Przykładami są użycie apikeys przez API. Nie sądzę, aby korzystanie z plików cookie lub uwierzytelniania HTTP kwalifikowało się.

Bjorn
źródło
Należy unikać plików cookie i uwierzytelniania HTTP ze względu na podatność CSRF.
Dobes Vandermeer
@DobesVandermeer Czy możesz zobaczyć moje pytanie, czy możesz pomóc? stackoverflow.com/questions/60111743/…
Hemant Metalia
12

Aktualizacja 16 lutego 2019 r

Podejście wspomniane wcześniej poniżej to w zasadzie rodzaj „ OAuth2.0 ” poświadczenia hasła właściciela zasobu . Jest to łatwy sposób na rozpoczęcie pracy. Jednak dzięki takiemu podejściu każda aplikacja w organizacji otrzyma własne mechanizmy uwierzytelniania i autoryzacji. Zalecane podejście to rodzaj dotacji „Kod autoryzacyjny”. Ponadto w mojej wcześniejszej odpowiedzi poniżej zaleciłem localStorage przeglądarki do przechowywania tokenów uwierzytelniania. Jednak doszedłem do wniosku, że ciasteczko jest odpowiednią opcją do tego celu. W tej odpowiedzi StackOverflow szczegółowo opisałem swoje powody, sposób implementacji typu przyznania kodu autoryzacji, względy bezpieczeństwa itp .


Myślę, że do uwierzytelnienia usługi REST można zastosować następujące podejście:

  1. Utwórz interfejs API RESTful logowania, aby zaakceptować nazwę użytkownika i hasło do uwierzytelnienia. Użyj metody HTTP POST, aby zapobiec buforowaniu i SSL dla bezpieczeństwa podczas transportu Po udanym uwierzytelnieniu interfejs API zwraca dwa JWT - jeden token dostępu (krótszy okres ważności, powiedzmy 30 minut) i jeden token odświeżania (dłuższy okres ważności, powiedzmy 24 godziny)
  2. Klient (internetowy interfejs użytkownika) przechowuje JWT w pamięci lokalnej i przy każdym kolejnym wywołaniu API przekazuje token dostępu w nagłówku „Authorization: Bearer #access token”
  3. Interfejs API sprawdza ważność tokena, weryfikując podpis i datę ważności. Jeśli token jest prawidłowy, sprawdź, czy użytkownik (interpretuje oświadczenie „sub” w JWT jako nazwę użytkownika) ma dostęp do interfejsu API z wyszukiwaniem pamięci podręcznej. Jeśli użytkownik jest uprawniony do dostępu do interfejsu API, uruchom logikę biznesową
  4. Jeśli token wygasł, interfejs API zwraca kod odpowiedzi HTTP 400
  5. Po otrzymaniu 400/401 klient wywołuje inny interfejs API REST z tokenem odświeżania w nagłówku „Authorization: Bearer #refresh token”, aby uzyskać nowy token dostępu.
  6. Po otrzymaniu połączenia z tokenem odświeżania sprawdź, czy token odświeżania jest prawidłowy, sprawdzając podpis i datę ważności. Jeśli token odświeżania jest prawidłowy, odśwież pamięć podręczną praw dostępu użytkownika z bazy danych i zwróć nowy token dostępu i token odświeżania. Jeśli token odświeżania jest nieprawidłowy, zwróć kod odpowiedzi HTTP 400
  7. Jeśli zostanie zwrócony nowy token dostępu i token odświeżania, przejdź do kroku 2. Jeśli zostanie zwrócony kod odpowiedzi HTTP 400, klient zakłada, że ​​token odświeżania wygasł i prosi użytkownika o podanie nazwy użytkownika i hasła
  8. Aby się wylogować, wyczyść pamięć lokalną

Dzięki takiemu podejściu wykonujemy kosztowną operację ładowania pamięci podręcznej z danymi praw dostępu specyficznymi dla użytkownika co 30 minut. Jeśli więc dostęp zostanie odwołany lub przyznany zostanie nowy dostęp, jego odzwierciedlenie zajmuje 30 minut lub wylogowanie następuje po zalogowaniu.

Saptarshi Basu
źródło
więc czy użyłbyś tego do interfejsu API ze statyczną stroną internetową wykonaną na przykład z angular? a co z aplikacjami mobilnymi?
Yazan Rawashdeh
8

W ten sposób można to zrobić: używając OAuth 2.0 do logowania .

Możesz używać innych metod uwierzytelniania niż Google, o ile obsługuje OAuth.

moshe beeri
źródło
1
OAuth2 nie jest bezpieczny bez HTTPS ani bezstanowy.
Arnaud Bouchez
4
Nic nie jest bezpieczne bez HTTPS.
Craig
1
@Craig i HTTPS również mogą nie być bezpieczne, jeśli łańcuch certyfikatów zostanie zerwany, co może być dla dobra - en.wikipedia.org/wiki/Bullrun_(decryption_program) ;)
Arnaud Bouchez
1
@ArnaudBouchez Proszę wyjaśnić, jak zepsuty łańcuch certyfikatów jest dla większego dobra? Nie rozumiem do czego zmierzasz. ;)
Craig
@Craig Postępuj zgodnie z linkiem i ciesz się! To podejście „większego dobra” było wyraźnie cyniczne w moim komentarzu: systemy podobne do Bullrun są przeznaczone dla „naszego własnego dobra” przez nasze ukochane i ufne rządy.
Arnaud Bouchez
3

Korzystanie z infrastrukcji klucza publicznego, w której rejestracja klucza wiąże się z odpowiednim wiązaniem, zapewnia, że ​​klucz publiczny jest powiązany z osobą, do której jest przypisany, w sposób zapewniający niezaprzeczenie

Zobacz http://en.wikipedia.org/wiki/Public_key_infrastructure . Jeśli przestrzegasz odpowiednich standardów PKI, osoba lub agent, który niewłaściwie używa skradzionego klucza, może zostać zidentyfikowany i zablokowany. Jeśli agent musi użyć certyfikatu, powiązanie staje się dość ścisłe. Sprytny i szybko poruszający się złodziej może uciec, ale pozostawiają więcej okruchów.

DonB.
źródło
2

Aby odpowiedzieć na to pytanie z mojego zrozumienia ...

System uwierzytelniania korzystający z usługi REST, dzięki czemu nie trzeba faktycznie śledzić użytkowników w systemie ani zarządzać nimi. Odbywa się to za pomocą metod HTTP POST, GET, PUT, DELETE. Przyjmujemy te 4 metody i myślimy o nich w kategoriach interakcji z bazą danych jako UTWÓRZ, ODCZYTAJ, AKTUALIZUJ, USUŃ (ale w Internecie używamy POST i GET, ponieważ obecnie obsługuje to tagi kotwicy). Więc traktując POST i GET jako nasz CREATE / READ / UPDATE / DELETE (CRUD), możemy zaprojektować trasy w naszej aplikacji internetowej, które będą w stanie wywnioskować, jakie działanie CRUD osiągamy.

Na przykład w aplikacji Ruby on Rails możemy zbudować naszą aplikację internetową, aby użytkownik zalogowany odwiedził stronę http://store.com/account/logout wówczas GET tej strony może być widziany jako użytkownik próbujący się wylogować . W naszym kontrolerze szyn zbudowalibyśmy akcję, która wylogowuje użytkownika i odsyła go z powrotem na stronę główną.

GET na stronie logowania dałoby formularz. test POST na stronie logowania byłby postrzegany jako próba zalogowania, zabrałby dane POST i użyłby ich do zalogowania.

Dla mnie jest to praktyka polegająca na stosowaniu metod HTTP zmapowanych do ich bazy danych, a następnie budowaniu systemu uwierzytelniania, mając na uwadze, że nie trzeba przekazywać identyfikatora sesji ani śledzić sesji.

Wciąż się uczę - jeśli znajdziesz coś, co powiedziałem, że jest złe, popraw mnie, a jeśli dowiesz się więcej, opublikuj to tutaj. Dzięki.


źródło
2

Wskazówki dotyczące zabezpieczania dowolnej aplikacji internetowej

Jeśli chcesz zabezpieczyć swoją aplikację, zdecydowanie powinieneś zacząć od HTTPS zamiast HTTP , to zapewnia utworzenie bezpiecznego kanału między tobą a użytkownikami, który zapobiegnie wąchaniu danych przesyłanych tam i z powrotem do użytkowników i pomoże zachować dane wymieniane poufne.

Możesz użyć JWT (JSON Web Tokeny) do zabezpieczenia interfejsów API RESTful , ma to wiele zalet w porównaniu do sesji po stronie serwera, korzyści to głównie:

1- Bardziej skalowalne, ponieważ serwery API nie będą musiały utrzymywać sesji dla każdego użytkownika (co może być dużym obciążeniem, gdy masz wiele sesji)

2- JWT są samodzielne i mają roszczenia, które określają na przykład rolę użytkownika oraz to, do czego może uzyskać dostęp i wydane w dniu i dacie ważności (po którym JWT nie będzie ważne)

3- Łatwiejsza obsługa w modułach równoważenia obciążenia, a jeśli masz wiele serwerów API, ponieważ nie będziesz musiał współużytkować danych sesji ani konfigurować serwera tak, aby kierował sesję do tego samego serwera, ilekroć żądanie z JWT trafi na dowolny serwer, może zostać uwierzytelnione i autoryzowany

4 - Mniejsza presja na twoją bazę danych, jak również nie będziesz musiał stale przechowywać i pobierać identyfikatora sesji i danych dla każdego żądania

5- Nie można manipulować JWT, jeśli użyjesz silnego klucza do podpisania JWT, więc możesz ufać roszczeniom w JWT, który jest wysyłany z żądaniem, bez konieczności sprawdzania sesji użytkownika i czy jest on autoryzowany, czy nie , możesz po prostu sprawdzić JWT, a następnie wszystko jest ustawione, aby wiedzieć, kto i co ten użytkownik może zrobić.

Wiele bibliotek zapewnia łatwe sposoby tworzenia i sprawdzania JWT w większości języków programowania, na przykład: w node.js jedną z najpopularniejszych jest jsonwebtoken

Ponieważ interfejsy API REST zasadniczo mają na celu utrzymanie bezstanowego serwera, dlatego JWT są bardziej zgodne z tą koncepcją, ponieważ każde żądanie jest wysyłane z tokenem autoryzacji, który jest samowystarczalny (JWT) bez konieczności śledzenia sesji użytkownika przez serwer w porównaniu do sesji, które sprawiają, że serwer stanowy, aby zapamiętał użytkownika i jego rolę, jednak sesje są również szeroko stosowane i mają swoje zalety, które możesz wyszukać, jeśli chcesz.

Jedną ważną rzeczą do zapamiętania jest to, że musisz bezpiecznie dostarczyć JWT do klienta za pomocą HTTPS i zapisać go w bezpiecznym miejscu (na przykład w lokalnej pamięci masowej).

Możesz dowiedzieć się więcej o JWT z tego linku

Ahmed Elkoussy
źródło