2009-02-13 12 views
151

Nota prawna: Jestem nowy w szkole myśli o REST i staram się owijać wokół niej myśli.Czy możesz mi pomóc to zrozumieć? "Częste błędy REST: sesje są nieistotne"

Tak, czytam tę stronę, Common REST Mistakes, i odkryłem, że jestem całkowicie zaskoczony, że sekcja poświęcona sesjom jest nieistotna. Oto, co mówi strona:

Klient " " nie musi już logować się ani "uruchamiać połączenia". Uwierzytelnianie HTTP jest wykonywane automatycznie przy każdej wiadomości w postaci . Aplikacje klienta są konsumentami zasobów , a nie usług. Dlatego nie ma nic do zalogowania się! Powiedzmy, że rezerwujesz lot w usłudze internetowej REST . Nie tworzysz nowego połączenia "sesyjnego" z usługą . Zamiast tego poprosić o "obiekt twórcy ", aby utworzyć nowy plan podróży . Możesz rozpocząć wypełnianie pustych pól, ale potem uzyskać zupełnie inny inny komponent w innym miejscu na stronie internetowej , aby wypełnić inne puste pola. Nie ma sesji, więc nie ma problemu z migracją stanu między klientami. Nie ma także numeru "powinowactwa sesji" na serwerze (chociaż nadal trzeba się liczyć z problemami dotyczącymi równoważenia, aby kontynuować).

OK, dostaję, że uwierzytelnianie HTTP odbywa się automatycznie przy każdej wiadomości - ale jak? Czy nazwa użytkownika/hasło są wysyłane przy każdym żądaniu? Czy to nie tylko zwiększa powierzchnię ataku? Czuję, że brakuje mi części układanki.

Czy byłoby źle mieć usługę REST, powiedzmy, /session, która akceptuje żądanie GET, gdzie można podać nazwę użytkownika/hasło jako część żądania, i zwraca token sesji, jeśli uwierzytelnienie się powiodło , które mogą być następnie przekazywane wraz z kolejnymi wnioskami? Czy to ma sens z punktu widzenia REST, czy jest to, że brakuje punktu?

Odpowiedz

76

Aby być REST, każde żądanie HTTP powinno zawierać wystarczającą ilość informacji, aby odbiorca mógł przetworzyć je w pełnej zgodności z bezpaństwowym charakterem HTTP.

Ok, rozumiem, że uwierzytelnianie HTTP odbywa się automatycznie na każdej wiadomości - ale jak?

Tak, nazwa użytkownika i hasło są wysyłane przy każdym żądaniu. Typowe metody to: podstawowe uwierzytelnianie dostępu i uwierzytelnianie dostępu do skrótu. I tak, podsłuchujący może przechwytywać referencje użytkownika. W ten sposób można szyfrować wszystkie dane wysłane i odebrane przy użyciu Transport Layer Security (TLS).

byłoby źle odpocząć usług, powiedzmy,/sesji, który akceptuje żądania Get, gdzie można by przekazać w nazwę użytkownika/hasło jako część żądania i zwraca token sesji , jeśli uwierzytelnienie się powiodło, , które można następnie przekazać wraz z kolejnymi żądaniami ? Czy to powoduje, że wartość jest określona z punktu widzenia REST, czy też jest , która nie zawiera punktu?

To nie byłoby relaksującego ponieważ niesie stan, ale to jest jednak dość powszechne, ponieważ jest to wygoda dla użytkowników; użytkownik nie musi się logować za każdym razem.

To, co opisujesz w "tokenie sesji", jest zwykle określane jako plik cookie logowania . Na przykład, jeśli próbujesz zalogować się do swojego konta Yahoo! konto jest pole wyboru, które mówi "keep me zalogowany przez 2 tygodnie". Zasadniczo jest to powiedzenie (według twoich słów) "utrzymuj mój znacznik sesji przy życiu przez 2 tygodnie, jeśli pomyślnie się zaloguję." Przeglądarki internetowe wyślą takie pliki cookie do logowania (i ewentualnie inne) przy każdym żądaniu HTTP, które poprosi się o nie.

+5

Ta odpowiedź nie ma dla mnie żadnego sensu. Po pierwsze, mówi, że wystarczy podać login i hasło za każdym razem, a więc i raz, co ma sens. Następnie sugerowany jest pomysł powrócenia do klienta pomyślnego stanu logowania w postaci tokena. W razie potrzeby token może kodować czas utworzenia. Z pewnością możemy zwrócić informacje do klienta. Tak więc ta sugestia wydaje mi się w porządku. Odpowiedź brzmi, że nie jest w porządku, ponieważ "niesie ze sobą stan", ale czy nie jest to "ST" w "REST", że stan można przenieść między klientem a serwerem? –

31

Często zdarza się, że usługa REST wymaga uwierzytelnienia dla każdego żądania HTTP. Na przykład usługa Amazon S3 wymaga, aby każde żądanie miało sygnaturę uzyskaną z poświadczeń użytkownika, dokładnego żądania wykonania i bieżącej chwili. Sygnatura ta jest łatwa do obliczenia po stronie klienta, może zostać szybko zweryfikowana przez serwer i ma ograniczone zastosowanie do atakującego, który przechwytuje ją (ponieważ jest oparty na bieżącym czasie).

+0

Uwielbiam to podejście. Zacznę używać go od razu. –

+3

+1, czy możesz rozwinąć: _ jest w ograniczonym zakresie dla atakującego, który przechwytuje go (ponieważ jest on oparty na bieżącym czasie)? czy nie mówisz o cookie zawierającym zaszyfrowaną nazwę użytkownika i hasło? podobnie jak SO? (IMHO) –

+1

@RoyiNamir: Nie mówię o cookie. Sygnatura używana przez S3 jest parametrem dla żądania HTTP, ale jest * nie * plikiem cookie, jest ponownie obliczana dla każdego żądania. –

3

Myślę, że Twoja sugestia jest OK, jeśli chcesz kontrolować czas życia sesji klienta. Myślę, że architektura RESTful zachęca do tworzenia aplikacji bezpaństwowych. Ponieważ @ 2pence napisał: "każde żądanie HTTP powinno zawierać wystarczającą ilość informacji, aby odbiorca mógł przetworzyć je w pełnej zgodności z bezpaństwowym charakterem HTTP".

Jednak nie zawsze tak jest, czasami aplikacja musi informować, kiedy klient loguje się lub wylogowuje, i aby utrzymywać zasoby, takie jak blokady lub licencje na podstawie tych informacji. Zobacz moją kontynuację question dla przykładu takiego przypadku.

5

Ok, rozumiem, że uwierzytelnianie HTTP odbywa się automatycznie na każdej wiadomości - ale jak?

"Autoryzacja:" nagłówek HTTP wysyłany przez klienta. Podstawowy (zwykły tekst) lub skrót.

byłoby źle odpocząć usług, powiedzmy,/sesji, który akceptuje żądania Get, gdzie można by przekazać w nazwę użytkownika/hasło jako część żądania i zwraca token sesji , jeśli uwierzytelnienie się powiodło, , które można następnie przekazać wraz z kolejnymi żądaniami ? Czy to powoduje, że wartość jest określona z punktu widzenia REST, czy też jest , która nie zawiera punktu?

Cała idea sesji jest, aby stanowe aplikacje wykorzystujące bezstanową Protocol (HTTP) i niemy klienta (przeglądarki internetowej), utrzymując stan po stronie serwera. Jedną z zasad REST jest "Każdy zasób jest wyjątkowo adresowalny przy użyciu uniwersalnej składni do użytku w hiper-hiper-linkach". Zmienne sesji są czymś, do czego nie można uzyskać dostępu za pomocą URI. Prawdziwie RESTful aplikacja zachowa stan po stronie klienta, wysyłając wszystkie potrzebne zmienne przez HTTP, najlepiej w URI.

Przykład: wyszukiwanie przy pomocy paginacji. Trzeba URL w postaci

http://server/search/urlencoded-search-terms/page_num 

To ma wiele wspólnego z ustawić zakładki URL

+4

Informacje uwierzytelniające nie są jednak dostępne za pośrednictwem identyfikatora URI - wszyscy mówią o wysłaniu informacji o autorze jako części nagłówka żądania. Czym różni się to od dołączania tokenu sesji do żądania? Nie mówię, że używaj tokena sesji w URI, ale w danych przekazanych w żądaniu. –

+0

Uwierzytelnianie zostaje ustanowione, jeśli masz uprawnienia do wykonania tej czynności, a w aplikacji RESTful nie wpłynie to na jego wynik. – vartec

+4

Token sesji ustanawia również, jeśli masz uprawnienia do wykonania tej akcji. Co masz na myśli, że nie wpłynie to na jego wynik? Jeśli osoba dzwoniąca nie jest autoryzowana, otrzyma komunikat "Brak autoryzacji". To samo z tokenem sesji. Naprawdę nie widzę różnicy? –

8

Nie, to nie mija się z celem. Google ClientLogin działa dokładnie w taki sposób, z godnym uwagi wyjątkiem, że klient jest poinstruowany, aby przejść do "/ session" za pomocą odpowiedzi HTTP 401. Ale to nie tworzy sesji, tworzy jedynie sposób, w jaki klienci mogą (tymczasowo) się uwierzytelniać bez przekazywania poświadczeń w stanie wyczyszczenia, a serwer kontroluje ważność tych tymczasowych poświadczeń, jakie uzna za stosowne.

+0

To nie wydaje się jednak zbyteczne. –

+11

@ unforgiven3 Dopóki zwrócony token służy tylko do uwierzytelnienia użytkownika i nie jest używany przez serwer do powiązania użytkownika z innym stanem przechowywanym na serwerze, nie widzę żadnych ograniczeń REST. –

+0

@Darrel, w jaki sposób można później uwierzytelnić kolejne żądania HTTP? Rozumiem, że uwierzytelnianie odbywa się przy każdym żądaniu HTTP. –

10

Wiele osób nie rozumie bardzo wyraźnie zasad REST, używanie tokenu sesji nie oznacza zawsze, że jesteś państwowy, powodem wysyłania nazwy użytkownika/hasła przy każdym żądaniu jest tylko uwierzytelnianie i to samo dla wysyłania tokena (generowane przez proces logowania) tylko po to, aby zdecydować, czy klient ma pozwolenie na żądanie danych, czy nie, tylko naruszasz koncesje REST, kiedy używasz nazwy użytkownika/hasła lub tokenów sesji, aby zdecydować, jakie dane pokazać! Zamiast tego należy używać ich tylko do atestowania (pokazywać dane lub nie pokazywać danych)

w twoim przypadku mówię TAK to jest RESTY, ale spróbuj unikać używania natywnych sesji php w interfejsie API REST i zacznij generować własne zakotwiczone żetony, które wygasają w określonym czasie!

+0

dziękuję. dlaczego należy unikać macierzystej sesji php i zamiast niej używać własnych tokenów skrótu? – Matthew

+0

Nie mam żadnego genialnego powodu, dla którego powiem, po prostu dla większego bezpieczeństwa i większej kontroli. – EvilThinker

+0

To jest lepsze niż zaakceptowana odpowiedź. Przynajmniej akceptuje sugestię jako RESTY, która ma sens. Nie rozumiem jednak, dlaczego przekazanych informacji nie można użyć do autoryzacji zależnej od użytkownika. Niektórzy użytkownicy mogą mieć dostęp do niektórych danych, a inni nie. To nie sprawia, że ​​protokół nie jest restestowany. –

Powiązane problemy