JavaScript: convalida lato client vs. lato server


179

Quale è meglio effettuare la convalida lato client o lato server?

Nella nostra situazione che stiamo usando

  • jQuery e MVC.
  • Dati JSON da passare tra la nostra vista e il controller.

Gran parte della convalida che faccio è la convalida dei dati quando gli utenti li inseriscono. Ad esempio, utilizzo l' keypressevento per impedire le lettere in una casella di testo, impostare un numero massimo di caratteri e un numero compreso in un intervallo.

Immagino che la domanda migliore sarebbe: ci sono dei vantaggi nel fare la convalida lato server sul lato client?


Fantastico risponde a tutti. Il sito Web che abbiamo è protetto da password e per una piccola base di utenti (<50). Se non eseguono JavaScript, invieremo ninja. Ma se stessimo progettando un sito per tutti, accetterei di fare la convalida da entrambe le parti.


2
javascript può essere disabilitato
Enrico Murru,

Non esiste un modo sicuro per bloccare gli utenti che disabilitano JavaScript. Se l'utente arriva alla tua pagina con JS abilitato e quindi lo disabilita, non c'è nulla che tu possa fare. (OK, potresti usare JS per implementare il controllo di invio, in modo che smetta di funzionare in questo scenario, ma questo può essere bypassato proprio come tutto il resto.)
Stewart

Risposte:


347

Come altri hanno già detto, dovresti fare entrambe le cose. Ecco perché:

Dalla parte del cliente

Desideri convalidare prima l'input sul lato client perché puoi fornire un feedback migliore all'utente medio . Ad esempio, se inseriscono un indirizzo e-mail non valido e passano al campo successivo, è possibile mostrare immediatamente un messaggio di errore. In questo modo l'utente può correggere tutti i campi prima di inviare il modulo.

Se esegui la convalida solo sul server, devono inviare il modulo, ricevere un messaggio di errore e provare a cercare il problema.

(Questo problema può essere attenuato facendo in modo che il server ritorni il modulo con l'input originale dell'utente compilato, ma la convalida sul lato client è ancora più veloce.)

Lato server

Vuoi convalidare sul lato server perché puoi proteggerti da un utente malintenzionato , che può facilmente aggirare il tuo JavaScript e inviare input pericolosi al server.

È molto pericoloso fidarsi dell'interfaccia utente. Non solo possono abusare dell'interfaccia utente, ma potrebbero non utilizzare affatto l'interfaccia utente o persino un browser . Cosa succede se l'utente modifica manualmente l'URL o esegue il proprio Javascript o modifica le richieste HTTP con un altro strumento? Che cosa succede se curl, ad esempio, inviano richieste HTTP personalizzate da o da uno script?

( Questo non è teorico; ad esempio, ho lavorato su un motore di ricerca di viaggi che ha inviato nuovamente la ricerca dell'utente a molte compagnie aeree partner, compagnie di autobus, ecc., Inviando POSTrichieste come se l'utente avesse compilato il modulo di ricerca di ciascuna società, quindi raccolto e ordinato tutti i risultati. Il modulo JS di quelle società non è mai stato eseguito ed è stato fondamentale per noi fornire messaggi di errore nell'HTML restituito. Ovviamente un'API sarebbe stata piacevole, ma questo era ciò che dovevamo fare. )

Non consentire ciò non è solo ingenuo dal punto di vista della sicurezza, ma anche non standard: un client dovrebbe essere autorizzato a inviare HTTP con qualsiasi mezzo desiderino e si dovrebbe rispondere correttamente. Ciò include la convalida.

La convalida lato server è importante anche per la compatibilità : non tutti gli utenti, anche se utilizzano un browser, avranno JavaScript abilitato.

Addendum - dicembre 2016

Esistono alcune convalide che non possono nemmeno essere eseguite correttamente nel codice dell'applicazione lato server e sono assolutamente impossibili nel codice lato client , poiché dipendono dallo stato corrente del database. Ad esempio, "nessun altro ha registrato tale nome utente" o "il post del blog su cui stai commentando esiste ancora" o "nessuna prenotazione esistente si sovrappone alle date richieste" o "il saldo del tuo account ha ancora abbastanza per coprire tale acquisto ". Solo il database può validare in modo affidabile i dati che dipendono dai dati correlati. Gli sviluppatori lo rovinano regolarmente , ma PostgreSQL offre alcune buone soluzioni .


30
Questa dovrebbe essere la risposta accettata, anche 6 anni dopo: P
Jacob McKay,

17
Sì, volevo aspettare quasi 10 anni per essere sicuro.
Brad8118,

2
@kidmosey "è un'ovvia violazione dei principi DRY" Sì, il che significa dolore per programmatori come noi. Ma immagina un modulo di iscrizione. Se la duplicazione della conoscenza "un indirizzo e-mail deve contenere una @" nel codice client significa che gli utenti ottengono un feedback più rapido e molti di loro si iscrivono, generando entrate extra di $ 100.000 all'anno, oltre a pagare per i costi di manutenzione extra. DRY è un ottimo principio, ma non è l'unica considerazione. La qualità del codice viene misurata in base al modo in cui serve gli utenti e un'organizzazione in un'analisi costi / benefici.
Nathan Long,

1
@ArunRaaj Sì, e affronterai la maggior parte dei problemi in questo modo, ma non è affidabile al 100%. Se due utenti stanno compilando il modulo contemporaneamente, è possibile che venga detto a entrambi che user1è un nome utente disponibile. Quando invieranno, otterranno entrambi lo stesso nome utente a meno che non ricontrolli sul lato server. E anche un controllo nel codice dell'applicazione del server può avere lo stesso problema: arrivano due richieste, la prima controlla il database e viene detto OK, la seconda controlla il database e viene detta OK, la prima viene salvata, la seconda viene salvata come duplicato. Solo un vincolo univoco db garantisce l'unicità.
Nathan Long,

1
@NathanLong Le convalide sui dati sensibili alle condizioni di gara non sono così intrattabili come questa frase le fa suonare. È una seccatura fare correttamente, ma creare un meccanismo di prenotazione che utilizza una risorsa sincronizzata da cui richiedere. Quindi se l'utente digita "usernameA" un controllo di unicità sul server che non consente più chiamate simultanee per verificare se univoci; se univoco, riservalo anche con un token temporaneo assegnato al client che viene rilasciato anche se un nome utente diverso viene testato dallo stesso ID sessione. Il token dovrebbe scadere dopo un tempo ragionevole. Esempio: prenotazione del posto TicketMaster.
Elaskanator,

79

Sì, la convalida lato client può essere totalmente ignorata, sempre. È necessario eseguire entrambe le operazioni, lato client per fornire una migliore esperienza utente e lato server per essere sicuri che l'input ottenuto sia effettivamente convalidato e non solo presumibilmente convalidato dal client.


43

Lo ripeterò, perché è abbastanza importante:

Convalida sempre sul server

e aggiungi JavaScript per la reattività dell'utente.


31

Il vantaggio di eseguire la convalida lato server rispetto alla convalida lato client è che la convalida lato client può essere ignorata / manipolata:

  • L'utente finale potrebbe aver disattivato JavaScript
  • I dati potrebbero essere inviati direttamente al tuo server da qualcuno che non sta nemmeno utilizzando il tuo sito, con un'app personalizzata progettata per farlo
  • Un errore Javascript sulla tua pagina (causato da un numero qualsiasi di cose) potrebbe comportare l'esecuzione di alcune convalide, ma non tutte

In breve, sempre, convalida sempre sul lato server e quindi considera la convalida sul lato client come un "extra" aggiunto per migliorare l'esperienza dell'utente finale.


18

Devi sempre convalidare sul server.

Anche la convalida sul client è utile per gli utenti, ma è assolutamente insicura.


9

Bene, trovo ancora spazio per rispondere.

Oltre alle risposte di Rob e Nathan, aggiungerei che avere convalide lato client è importante. Quando si applicano le convalide sui moduli Web, è necessario seguire queste linee guida:

Dalla parte del cliente

  1. È necessario utilizzare le convalide lato client per filtrare le richieste autentiche provenienti da utenti reali sul tuo sito Web.
  2. La convalida sul lato client deve essere utilizzata per ridurre gli errori che potrebbero verificarsi durante l'elaborazione sul lato server.
  3. La convalida sul lato client deve essere utilizzata per ridurre al minimo i round trip sul lato server in modo da risparmiare larghezza di banda e richieste per utente.

Lato server

  1. NON DOVREI presupporre che la convalida eseguita con successo sul lato client sia perfetta al 100%. Non importa se serve meno di 50 utenti. Non sai mai quale dei tuoi utenti / dipendenti si trasforma in un "male" e fai qualche attività dannosa sapendo che non hai validazioni adeguate in atto.
  2. Anche se è perfetto in termini di convalida dell'indirizzo e-mail, numeri di telefono o controllo di alcuni input validi, potrebbe contenere dati molto dannosi. Che deve essere filtrato sul lato server, non importa se è corretto o errato.
  3. Se la convalida sul lato client viene ignorata, le convalide sul lato server vengono per salvarti da qualsiasi potenziale danno all'elaborazione sul lato server. In tempi recenti, abbiamo già sentito molte storie di iniezioni SQL e altri tipi di tecniche che potrebbero essere applicate al fine di ottenere alcuni benefici malvagi.

Entrambi i tipi di convalide svolgono ruoli importanti nei rispettivi ambiti, ma il più efficace è quello lato server. Se ricevi 10k utenti in un unico momento, finiresti per filtrare il numero di richieste che arrivano al tuo server web. Se riscontri un singolo errore come un indirizzo email non valido, inviano nuovamente il modulo e chiedono al tuo utente di correggerlo, che consumerà sicuramente le risorse del tuo server e la larghezza di banda. Quindi meglio applicare la convalida JavaScript. Se javascript è disabilitato, la tua convalida lato server verrà in soccorso e scommetto che solo pochi utenti potrebbero averlo disabilitato accidentalmente poiché il 99,99% dei siti Web utilizza javascript ed è già abilitato per impostazione predefinita in tutti i browser moderni.


Ho visto persone trascurare di proteggere completamente dall'iniezione di codice, non importa farlo solo dal lato client. E nessun riferimento all'iniezione di codice è completo senza un link a questo: xkcd.com/327 :)
Stewart

8

È possibile eseguire la convalida lato server e rispedire indietro un oggetto JSON con i risultati della convalida per ciascun campo, mantenendo al minimo Javascript client (solo visualizzazione dei risultati) e mantenendo comunque un'esperienza user friendly senza dover ripetere se stessi sia sul client che sul server.


3
Di facile utilizzo? Può essere. Quasi istantaneo e burroso liscio? Probabilmente no.
quadrupleslap,

4

Il lato client dovrebbe utilizzare una convalida di base tramite i tipi di input HTML5 e gli attributi di pattern e poiché questi vengono utilizzati solo per miglioramenti progressivi per una migliore esperienza utente (anche se non sono supportati su <IE9 e Safari, ma non ci affidiamo a essi). Ma la convalida principale dovrebbe avvenire sul lato server.


"Ma la convalida principale dovrebbe avvenire sul lato server." Non dovrebbe, deve.
Stewart,


2

JavaScript può essere modificato in fase di esecuzione.

Suggerisco un modello per creare una struttura di validazione sul server e condividerla con il client.

Avrai bisogno di una logica di convalida separata su entrambe le estremità, ad esempio:

"required"attributi sul inputslato client

field.length > 0 lato server.

Tuttavia, l'utilizzo della stessa specifica di convalida eliminerà una certa ridondanza (ed errori) del mirroring della convalida su entrambe le estremità.


2

La convalida dei dati lato client può essere utile per una migliore esperienza utente: ad esempio, un utente che digita erroneamente il suo indirizzo e-mail, non dovrebbe attendere che la sua richiesta venga elaborata da un server remoto per conoscere l'errore di battitura che ha fatto.

Tuttavia, poiché un utente malintenzionato può ignorare la convalida lato client (e potrebbe addirittura non utilizzare affatto il browser), è necessaria la convalida lato server e deve essere la vera porta per proteggere il back-end da utenti malvagi.


1

Mi sono imbattuto in un collegamento interessante che fa una distinzione tra errori grossolani, sistematici e casuali.

Client-Side validationsi adatta perfettamente per prevenire errori grossolani e casuali. In genere una lunghezza massima per trama e input. Non imitare la regola di convalida sul lato server; fornire la propria regola di convalida della regola empirica grossolana (es. 200 caratteri sul lato client; nsul lato server dettati da una solida regola aziendale).

Server-side validationsi adatta perfettamente alla prevenzione di errori sistematici; imporrà regole commerciali.

In un progetto in cui sono coinvolto, la convalida viene eseguita sul server tramite richieste Ajax. Sul client visualizzo i messaggi di errore di conseguenza.

Ulteriori letture: errori grossolani, sistematici, casuali:

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


-2

Se stai eseguendo una validazione leggera, è meglio farlo sul client. Salverà il traffico di rete che aiuterà il tuo server a funzionare meglio. Se complicasse la convalida che comporta l'estrazione di dati da un database o qualcosa del genere, come le password, è meglio farlo sul server in cui i dati possono essere controllati in modo sicuro.


2
Quello che stai pubblicizzando non è la migliore idea. L'utente può sempre ignorare la convalida sul lato client e inviare ciò che desidera al database.
kremuwa,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.