JavaScript: sprawdzanie poprawności po stronie klienta vs. po stronie serwera

179

Co lepiej zrobić po stronie klienta lub po stronie serwera?

W naszej sytuacji korzystamy

  • jQuery i MVC.
  • Dane JSON przekazywane między naszym Widokiem a Kontrolerem.

Dużą część weryfikacji, którą wykonuję, polega na sprawdzaniu poprawności danych podczas ich wprowadzania przez użytkowników. Na przykład używam keypresszdarzenia, aby zapobiec literom w polu tekstowym, ustawić maksymalną liczbę znaków i liczbę z zakresu.

Wydaje mi się, że lepszym pytaniem byłoby: Czy są jakieś korzyści z przeprowadzania weryfikacji po stronie serwera po stronie klienta?


Niesamowite odpowiedzi dla wszystkich. Nasza strona internetowa jest chroniona hasłem i dla małej grupy użytkowników (<50). Jeśli nie obsługują JavaScript, wyślemy ninja. Ale jeśli projektujemy witrynę dla wszystkich, zgodziłbym się przeprowadzić walidację po obu stronach.

Brad8118
źródło
2
javascript można wyłączyć
Enrico Murru
Nie ma pewnego sposobu na zablokowanie użytkowników, którzy wyłączają JavaScript. Jeśli użytkownik wejdzie na twoją stronę z włączoną JS, a następnie ją wyłączy, nic nie możesz zrobić. (OK, możesz użyć JS do zaimplementowania kontroli przesyłania, aby przestał działać w tym scenariuszu, ale można to obejść jak wszystko inne.)
Stewart

Odpowiedzi:

347

Jak powiedzieli inni, powinieneś zrobić jedno i drugie. Dlatego:

Strona klienta

Chcesz najpierw zweryfikować dane wejściowe po stronie klienta, ponieważ możesz przekazać lepszą opinię przeciętnemu użytkownikowi . Na przykład, jeśli wprowadzą nieprawidłowy adres e-mail i przejdą do następnego pola, możesz natychmiast wyświetlić komunikat o błędzie. W ten sposób użytkownik może poprawić każde pole przed przesłaniem formularza.

Jeśli weryfikujesz tylko na serwerze, muszą oni przesłać formularz, otrzymać komunikat o błędzie i spróbować wyśledzić problem.

(Ten ból można złagodzić poprzez ponowne renderowanie formularza przez serwer z wypełnieniem oryginalnych danych wejściowych użytkownika, ale sprawdzanie poprawności po stronie klienta jest jeszcze szybsze.)

Po stronie serwera

Chcesz sprawdzić poprawność po stronie serwera, ponieważ możesz chronić się przed złośliwym użytkownikiem , który może łatwo ominąć JavaScript i przesyłać niebezpieczne dane na serwer.

Ufanie interfejsowi użytkownika jest bardzo niebezpieczne. Mogą nie tylko nadużywać interfejsu użytkownika, ale mogą w ogóle nie używać interfejsu użytkownika, a nawet przeglądarki . Co się stanie, jeśli użytkownik ręcznie edytuje adres URL, uruchomi własny JavaScript lub poprawi swoje żądania HTTP za pomocą innego narzędzia? Co się stanie, jeśli wyślą niestandardowe żądania HTTP curlze skryptu lub ze skryptu?

( To nie jest teoretyczne; np. Pracowałem nad wyszukiwarką podróży, która ponownie przesłała wyszukiwanie użytkownika do wielu partnerskich linii lotniczych, firm autobusowych itp., Wysyłając POSTżądania tak, jakby użytkownik wypełnił formularz wyszukiwania każdej firmy, a następnie zebrał i posortował wszystkie wyniki. Formularz JS tych firm nigdy nie został wykonany, a dla nas kluczowe było dostarczenie komunikatów o błędach w zwróconym HTML. Oczywiście interfejs API byłby fajny, ale właśnie to musieliśmy zrobić. )

Nie zezwalanie na to jest nie tylko naiwne z punktu widzenia bezpieczeństwa, ale także niestandardowe: klient powinien mieć możliwość wysyłania HTTP w dowolny sposób i powinien odpowiedzieć poprawnie. Obejmuje to walidację.

Sprawdzanie poprawności po stronie serwera jest również ważne dla zgodności - nie wszyscy użytkownicy, nawet jeśli korzystają z przeglądarki, będą mieli włączoną obsługę JavaScript.

Dodatek - grudzień 2016 r

Istnieją pewne weryfikacje, których nie można nawet poprawnie wykonać w kodzie aplikacji po stronie serwera i są one całkowicie niemożliwe w kodzie po stronie klienta , ponieważ zależą one od bieżącego stanu bazy danych. Na przykład „nikt inny nie zarejestrował tej nazwy użytkownika”, „wpis na blogu, który komentujesz, nadal istnieje” lub „żadna istniejąca rezerwacja nie pokrywa się z żądanymi datami” lub „saldo konta wciąż wystarcza na pokrycie tego zakupu . ” Tylko baza danych może niezawodnie sprawdzać poprawność danych, które zależą od powiązanych danych. Programiści regularnie to psują , ale PostgreSQL zapewnia dobre rozwiązania .

Nathan Long
źródło
30
To powinna być zaakceptowana odpowiedź, nawet 6 lat później: P
Jacob McKay
17
Tak, chciałem poczekać prawie 10 lat, aby się upewnić.
Brad8118,
2
@kidmosey ”to oczywiste naruszenie zasad OSUSZANIA” Tak, co oznacza ból dla programistów takich jak my. Ale wyobraź sobie formularz rejestracyjny. Jeśli powielenie wiedzy „adres e-mail musi zawierać @” w kodzie klienta oznacza, że ​​użytkownicy otrzymują szybszą informację zwrotną, a więcej z nich się rejestruje, co daje dodatkowy przychód w wysokości 100 000 USD rocznie, to więcej niż kosztuje dodatkowe koszty utrzymania. SUSZENIE to bardzo dobra zasada, ale to nie jedyna uwaga. Jakość kodu jest naprawdę mierzona w tym, jak dobrze służy użytkownikom i organizacji w analizie kosztów i korzyści.
Nathan Long,
1
@ArunRaaj Tak, w ten sposób złapiesz większość problemów, ale nie jest to w 100% niezawodne. Jeśli dwóch użytkowników wypełnia formularz w tym samym czasie, obaj mogą zostać poinformowani, że user1jest to dostępna nazwa użytkownika. Po przesłaniu obydwoje otrzymają tę samą nazwę użytkownika, chyba że ponownie sprawdzisz stronę serwera. I nawet sprawdzenie kodu aplikacji serwera może mieć ten sam problem: przychodzą dwa żądania, pierwsze sprawdza bazę danych i otrzymuje komunikat OK, drugie sprawdza bazę danych i wyświetla komunikat OK, pierwszy zapisywany, drugi zapisywany jako duplikat. Tylko ograniczenie unikalne db gwarantuje wyjątkowość.
Nathan Long
1
@NathanLong Sprawdzanie poprawności danych wrażliwych na warunki wyścigu nie jest tak trudne, jak to zdanie sprawia, że ​​brzmią dobrze. Uciążliwe jest prawidłowe działanie, ale utwórz mechanizm rezerwacji, który używa zsynchronizowanego zasobu do żądania. Jeśli więc użytkownik wpisze „nazwa użytkownikaA”, na serwerze sprawdza unikalność, która uniemożliwia wiele jednoczesnych wywołań w celu sprawdzenia, czy jest unikalna; jeśli jest unikalny, należy go również zarezerwować tymczasowym tokenem przypisanym do klienta, który jest również zwalniany, jeśli inna nazwa użytkownika jest testowana pod tym samym identyfikatorem sesji. Token powinien wygasnąć po upływie rozsądnego czasu. Przykład: rezerwa miejsc TicketMaster.
Elaskanator
79

Tak, zawsze można całkowicie sprawdzić poprawność po stronie klienta. Musisz zrobić zarówno po stronie klienta, aby zapewnić lepszą obsługę, jak i po stronie serwera, aby upewnić się, że otrzymane dane wejściowe są faktycznie sprawdzane, a nie tylko rzekomo sprawdzane przez klienta.

Vinko Vrsalovic
źródło
43

Powtórzę to, ponieważ jest to dość ważne:

Zawsze sprawdzaj poprawność na serwerze

i dodaj JavaScript, aby reagować na potrzeby użytkownika.

Toby Hede
źródło
31

Zaletą przeprowadzania sprawdzania poprawności po stronie serwera w porównaniu do sprawdzania poprawności po stronie klienta jest to, że sprawdzanie poprawności po stronie klienta można obejść / zmienić:

  • Użytkownik końcowy mógł wyłączyć javascript
  • Dane mogą być przesyłane bezpośrednio na Twój serwer przez osobę, która nawet nie korzysta z Twojej witryny, za pomocą zaprojektowanej do tego niestandardowej aplikacji
  • Błąd JavaScript na twojej stronie (spowodowany dowolną liczbą rzeczy) może spowodować, ale nie wszystkie, sprawdzenie poprawności

Krótko mówiąc - zawsze zawsze sprawdzaj poprawność po stronie serwera, a następnie rozważ weryfikację po stronie klienta jako dodatkowy „dodatek” w celu zwiększenia zadowolenia użytkownika końcowego.

Obrabować
źródło
18

Zawsze musisz sprawdzić poprawność na serwerze.

Również sprawdzanie poprawności na kliencie jest miłe dla użytkowników, ale jest całkowicie niepewne.

Peter Boughton
źródło
9

Nadal znajduję miejsce na odpowiedź.

Oprócz odpowiedzi Roba i Nathana dodam, że ważność ma weryfikacja po stronie klienta. Podczas sprawdzania poprawności formularzy internetowych należy przestrzegać następujących wskazówek:

Strona klienta

  1. Należy użyć weryfikacji po stronie klienta, aby odfiltrować autentyczne żądania pochodzące od autentycznych użytkowników w Twojej witrynie.
  2. Sprawdzanie poprawności po stronie klienta powinno być stosowane w celu zmniejszenia liczby błędów, które mogą wystąpić podczas przetwarzania po stronie serwera.
  3. Sprawdzanie poprawności po stronie klienta powinno być stosowane w celu zminimalizowania podróży w obie strony po stronie serwera, aby zaoszczędzić przepustowość i liczbę żądań przypadających na użytkownika.

Po stronie serwera

  1. NIE NALEŻY zakładać, że sprawdzanie poprawności przeprowadzone po stronie klienta jest w 100% idealne. Bez względu na to, czy obsługuje mniej niż 50 użytkowników. Nigdy nie wiadomo, który z użytkowników / pracowników zmienia się w „zło” i wykonuje szkodliwe działania, wiedząc, że nie ma odpowiednich poprawek.
  2. Nawet jeśli jest doskonały pod względem sprawdzania poprawności adresu e-mail, numerów telefonów lub sprawdzania poprawnych danych wejściowych, może zawierać bardzo szkodliwe dane. Które należy filtrować po stronie serwera, bez względu na to, czy jest poprawne czy niepoprawne.
  3. Jeśli pominie się sprawdzanie poprawności po stronie klienta, sprawdzanie poprawności po stronie serwera ma na celu uratowanie użytkownika przed potencjalnym uszkodzeniem przetwarzania po stronie serwera. W ostatnim czasie słyszeliśmy już wiele historii o iniekcjach SQL i innych technikach, które można zastosować w celu uzyskania złych korzyści.

Oba typy walidacji odgrywają ważną rolę w ich zakresie, ale najsilniejsza jest po stronie serwera. Jeśli otrzymujesz 10 000 użytkowników w jednym momencie, to na pewno skończyłbyś filtrowaniem liczby żądań przychodzących do twojego serwera. Jeśli stwierdzisz, że wystąpił pojedynczy błąd, taki jak nieprawidłowy adres e-mail, wówczas ponownie przesyła formularz z powrotem i prosi użytkownika o poprawienie go, co z pewnością zużyje zasoby serwera i przepustowość. Lepiej więc zastosuj sprawdzanie poprawności javascript. Jeśli javascript jest wyłączony, twoja weryfikacja po stronie serwera przyjdzie na ratunek i założę się, że tylko kilku użytkowników mogło go przypadkowo wyłączyć, ponieważ 99,99% stron używa javascript i jest już domyślnie włączony we wszystkich nowoczesnych przeglądarkach.

KMX
źródło
Widziałem, jak ludzie całkowicie zaniedbują ochronę przed wstrzyknięciem kodu, nie wspominając o tym, że robią to tylko po stronie klienta. Żadne odniesienie do wstrzykiwania kodu nie jest kompletne bez linku do tego: xkcd.com/327 :)
Stewart
8

Możesz przeprowadzić walidację po stronie serwera i odesłać obiekt JSON z wynikami walidacji dla każdego pola, ograniczając do minimum obsługę Javascript Javascript (tylko wyświetlanie wyników) i nadal zapewniając przyjazną obsługę bez konieczności powtarzania się na kliencie i serwerze.

Jonathan
źródło
3
Przyjazny użytkownikowi? Może. Prawie natychmiastowa i maślana gładka? Prawdopodobnie nie.
quadrupleslap
4

Po stronie klienta należy zastosować podstawową weryfikację za pomocą typów danych wejściowych HTML5 i atrybutów wzorca, ponieważ są one używane tylko do progresywnych ulepszeń dla lepszego doświadczenia użytkownika (nawet jeśli nie są obsługiwane na <IE9 i safari, ale nie polegamy na nich). Ale główna weryfikacja powinna nastąpić po stronie serwera.

adardesign
źródło
„Ale główna weryfikacja powinna nastąpić po stronie serwera”. Nie powinienem.
Stewart
2

JavaScript można modyfikować w czasie wykonywania.

Sugeruję wzorzec tworzenia struktury sprawdzania poprawności na serwerze i udostępniania jej klientowi.

Będziesz potrzebował osobnej logiki sprawdzania poprawności na obu końcach, np .:

"required"atrybuty po inputsstronie klienta

field.length > 0 po stronie serwera.

Ale użycie tej samej specyfikacji sprawdzania poprawności wyeliminuje nadmiarowość (i błędy) sprawdzania poprawności kopii lustrzanej na obu końcach.

TaylorMac
źródło
2

Sprawdzanie poprawności danych po stronie klienta może być przydatne dla lepszego doświadczenia użytkownika: na przykład ja, użytkownik, który źle wpisuje swój adres e-mail, nie powinienem czekać, aż jego żądanie zostanie przetworzone przez zdalny serwer, aby dowiedzieć się o literówce, którą zrobił.

Niemniej jednak, ponieważ atakujący może ominąć sprawdzanie poprawności po stronie klienta (a nawet w ogóle nie może korzystać z przeglądarki), sprawdzanie poprawności po stronie serwera jest wymagane i musi być prawdziwą bramą chroniącą backend przed złośliwymi użytkownikami.

Billal Begueradj
źródło
1

Natrafiłem na interesujący link, który rozróżnia rażące, systematyczne, losowe błędy.

Client-Side validationdoskonale nadaje się do zapobiegania rażącym i przypadkowym błędom. Zazwyczaj maksymalna długość tekstury i nakładu. Nie naśladuj reguły sprawdzania poprawności po stronie serwera; wprowadź własną regułę sprawdzania poprawności brutto (np. 200 znaków po stronie klienta;n po stronie serwera podyktowaną silną regułą biznesową).

Server-side validationdoskonale nadaje się do zapobiegania systematycznym błędom; będzie egzekwować reguły biznesowe.

W projekcie, w który jestem zaangażowany, sprawdzanie poprawności odbywa się na serwerze poprzez żądania ajax. Na kliencie odpowiednio wyświetlam komunikaty o błędach.

Dalsza lektura: błędy rażące, systematyczne, losowe:

https://answers.yahoo.com/question/index?qid=20080918203131AAEt6GO

roland
źródło
-2

Jeśli przeprowadzasz lekką weryfikację, najlepiej zrobić to na kliencie. Pozwoli to zaoszczędzić ruch sieciowy, co pomoże serwerowi działać lepiej. Jeśli skomplikowanie sprawdzania poprawności wymaga pobrania danych z bazy danych lub czegoś takiego, jak hasła, najlepiej zrobić to na serwerze, na którym można bezpiecznie sprawdzić dane.

Tomek
źródło
2
To, co reklamujesz, nie jest najlepszym pomysłem. Użytkownik zawsze może ominąć weryfikację po stronie klienta i przesłać do bazy danych, co chce.
kremuwa