JavaScript: validation côté client vs côté serveur

186

Quel est le meilleur moyen d'effectuer une validation côté client ou côté serveur?

Dans notre situation, nous utilisons

  • jQuery et MVC.
  • Données JSON à passer entre notre vue et notre contrôleur.

Une grande partie de la validation que je fais consiste à valider les données au fur et à mesure que les utilisateurs les saisissent. Par exemple, j'utilise l' keypressévénement pour empêcher les lettres dans une zone de texte, définir un nombre maximal de caractères et qu'un nombre se trouve dans une plage.

Je suppose que la meilleure question serait: y a-t-il des avantages à faire une validation côté serveur par rapport au client?


Génial répond à tout le monde. Le site Web que nous avons est protégé par mot de passe et est destiné à une petite base d'utilisateurs (<50). S'ils n'utilisent pas JavaScript, nous enverrons des ninjas. Mais si nous concevions un site pour tout le monde, j'accepterais de faire une validation des deux côtés.

Brad8118
la source
3
javascript peut être désactivé
Enrico Murru
Il n'y a aucun moyen sûr de bloquer les utilisateurs qui désactivent JavaScript. Si l'utilisateur accède à votre page avec JS activé, puis le désactive, vous ne pouvez rien faire. (OK, vous pouvez utiliser JS pour implémenter le contrôle de soumission, afin qu'il cesse de fonctionner dans ce scénario, mais cela peut être contourné comme tout le reste.)
Stewart

Réponses:

356

Comme d'autres l'ont dit, vous devriez faire les deux. Voici pourquoi:

Côté client

Vous souhaitez d'abord valider les entrées côté client, car vous pouvez donner de meilleurs commentaires à l'utilisateur moyen . Par exemple, s'ils entrent une adresse e-mail non valide et passent au champ suivant, vous pouvez afficher un message d'erreur immédiatement. De cette façon, l'utilisateur peut corriger chaque champ avant d' envoyer le formulaire.

Si vous validez uniquement sur le serveur, ils doivent soumettre le formulaire, obtenir un message d'erreur et essayer de rechercher le problème.

(Cette douleur peut être atténuée en demandant au serveur de restituer le formulaire avec l'entrée d'origine de l'utilisateur remplie, mais la validation côté client est encore plus rapide.)

Du côté serveur

Vous souhaitez valider côté serveur car vous pouvez vous protéger contre l'utilisateur malveillant , qui peut facilement contourner votre JavaScript et soumettre des entrées dangereuses au serveur.

Il est très dangereux de faire confiance à votre interface utilisateur. Non seulement ils peuvent abuser de votre interface utilisateur, mais ils peuvent ne pas utiliser du tout votre interface utilisateur, ni même un navigateur . Que faire si l'utilisateur modifie manuellement l'URL, ou exécute son propre Javascript, ou modifie ses requêtes HTTP avec un autre outil? Et s'ils envoient des requêtes HTTP personnalisées à partir curlou à partir d'un script, par exemple?

( Ce n'est pas théorique; par exemple, j'ai travaillé sur un moteur de recherche de voyages qui a renvoyé la recherche de l'utilisateur à de nombreuses compagnies aériennes partenaires, compagnies de bus, etc., en envoyant des POSTdemandes comme si l'utilisateur avait rempli le formulaire de recherche de chaque entreprise, puis rassemblé et trié tous les résultats. Le formulaire JS de ces entreprises n'a jamais été exécuté, et il était crucial pour nous qu'ils fournissent des messages d'erreur dans le code HTML renvoyé. Bien sûr, une API aurait été bien, mais c'était ce que nous devions faire. )

Ne pas autoriser cela est non seulement naïf du point de vue de la sécurité, mais aussi non standard: un client doit être autorisé à envoyer HTTP par tous les moyens qu'il souhaite, et vous devez répondre correctement. Cela inclut la validation.

La validation côté serveur est également importante pour la compatibilité - tous les utilisateurs, même s'ils utilisent un navigateur, n'auront pas activé JavaScript.

Addendum - décembre 2016

Certaines validations ne peuvent même pas être correctement effectuées dans le code d'application côté serveur et sont totalement impossibles dans le code côté client , car elles dépendent de l'état actuel de la base de données. Par exemple, "personne d'autre n'a enregistré ce nom d'utilisateur", ou "le billet de blog sur lequel vous commentez existe toujours", ou "aucune réservation existante ne chevauche les dates que vous avez demandées", ou "le solde de votre compte est encore suffisant pour couvrir cet achat . " Seule la base de données peut valider de manière fiable les données qui dépendent des données associées. Les développeurs gâchent régulièrement cela , mais PostgreSQL fournit de bonnes solutions .

Nathan Long
la source
Avec l'avènement de REST, le seul avantage de la validation côté client est d'éviter un déplacement vers le serveur. Étant donné que la validation côté client devra être dupliquée sur le serveur, il s'agit d'une violation évidente des principes DRY pour effectuer la validation client, qui ne peut même pas être fiable.
kidmosey
2
@kidmosey "c'est une violation évidente des principes de DRY" Oui, ce qui fait souffrir les programmeurs comme nous. Mais imaginez un formulaire d'inscription. Si la duplication de la connaissance "une adresse e-mail doit contenir un @" dans le code client signifie que les utilisateurs obtiennent des commentaires plus rapides et que davantage d'entre eux s'inscrivent, ce qui entraîne un revenu supplémentaire de 100 000 $ par an, cela paie largement les coûts de maintenance supplémentaires. DRY est un très bon principe, mais ce n'est pas la seule considération. La qualité du code est vraiment mesurée par la façon dont il sert les utilisateurs et une organisation dans une analyse coûts / avantages.
Nathan Long
"personne d'autre n'a enregistré ce nom d'utilisateur" cette validation n'est-elle pas possible côté client, lorsque vous utilisez Ajax?
Arun Raaj
1
@ArunRaaj Oui, et vous attraperez la plupart des problèmes de cette façon, mais ce n'est pas fiable à 100%. Si deux utilisateurs remplissent le formulaire en même temps, ils peuvent tous les deux être informés qu'il user1s'agit d'un nom d'utilisateur disponible. Lorsqu'ils soumettent, ils recevront tous les deux le même nom d'utilisateur, sauf si vous revérifiez côté serveur. Et même une vérification dans le code de l'application serveur peut avoir le même problème: deux requêtes arrivent, la première vérifie la base de données et se fait dire OK, la seconde vérifie la base de données et se dit OK, la première est enregistrée, la seconde est enregistrée en double. Seule une contrainte db unique garantit l'unicité.
Nathan Long
1
@NathanLong Les validations sur les données sensibles aux conditions de course ne sont pas aussi insolubles que cette phrase le fait paraître. C'est difficile à faire correctement, mais créez un mécanisme de réservation qui utilise une ressource synchronisée pour demander. Donc, si l'utilisateur tape "usernameA", une vérification d'unicité sur le serveur qui interdit plusieurs appels simultanés pour vérifier si elle est unique; s'il est unique, réservez-le également avec un jeton temporaire attribué au client qui est également libéré si un nom d'utilisateur différent est testé par le même ID de session. Le jeton doit expirer après un délai raisonnable. Exemple: réserve de siège TicketMaster.
Elaskanator
79

Oui, la validation côté client peut être totalement contournée, toujours. Vous devez faire les deux, côté client pour offrir une meilleure expérience utilisateur, et côté serveur pour être sûr que l'entrée que vous obtenez est réellement validée et pas seulement supposément validée par le client.

Vinko Vrsalovic
la source
43

Je vais juste le répéter, car c'est assez important:

Validez toujours sur le serveur

et ajoutez JavaScript pour la réactivité de l'utilisateur.

Toby Hede
la source
31

L'avantage de la validation côté serveur par rapport à la validation côté client est que la validation côté client peut être contournée / manipulée:

  • L'utilisateur final peut avoir désactivé javascript
  • Les données peuvent être envoyées directement à votre serveur par quelqu'un qui n'utilise même pas votre site, avec une application personnalisée conçue pour le faire
  • Une erreur Javascript sur votre page (causée par un certain nombre de choses) peut entraîner l'exécution d'une partie, mais pas de la totalité, de votre validation

En bref - toujours, toujours valider côté serveur, puis considérer la validation côté client comme un «extra» supplémentaire pour améliorer l'expérience de l'utilisateur final.

Rob
la source
18

Vous devez toujours valider sur le serveur.

Avoir également une validation sur le client est bien pour les utilisateurs, mais n'est absolument pas sûr.

Peter Boughton
la source
9

Eh bien, je trouve encore de la place pour répondre.

En plus des réponses de Rob et Nathan, j'ajouterais que les validations côté client sont importantes. Lorsque vous appliquez des validations sur vos formulaires Web, vous devez suivre ces instructions:

Côté client

  1. Vous devez utiliser des validations côté client afin de filtrer les demandes authentiques provenant d'utilisateurs authentiques de votre site Web.
  2. La validation côté client doit être utilisée pour réduire les erreurs pouvant survenir lors du traitement côté serveur.
  3. La validation côté client doit être utilisée pour minimiser les allers-retours côté serveur afin d'économiser la bande passante et les demandes par utilisateur.

Du côté serveur

  1. Vous NE DEVRIEZ PAS supposer que la validation effectuée avec succès côté client est parfaite à 100%. Peu importe même s'il dessert moins de 50 utilisateurs. Vous ne savez jamais lequel de votre utilisateur / employé se transforme en "mal" et fait une activité nuisible en sachant que vous n'avez pas les validations appropriées en place.
  2. Même si c'est parfait en termes de validation d'adresse e-mail, de numéros de téléphone ou de vérification de certaines entrées valides, il peut contenir des données très dangereuses. Qui doit être filtré côté serveur, que ce soit correct ou incorrect.
  3. Si la validation côté client est contournée, vos validations côté serveur viennent vous sauver de tout dommage potentiel à votre traitement côté serveur. Ces derniers temps, nous avons déjà entendu beaucoup d'histoires d'injections SQL et d'autres types de techniques qui pourraient être appliquées afin d'obtenir de mauvais avantages.

Les deux types de validations jouent un rôle important dans leur portée respective, mais le plus fort est le côté serveur. Si vous recevez 10 000 utilisateurs à un moment donné, vous finirez certainement par filtrer le nombre de demandes arrivant sur votre serveur Web. Si vous constatez qu'il y avait une seule erreur comme une adresse e-mail invalide, ils envoient à nouveau le formulaire et demandent à votre utilisateur de le corriger, ce qui consommera certainement les ressources et la bande passante de votre serveur. Mieux vaut donc appliquer la validation javascript. Si javascript est désactivé, la validation côté serveur viendra à la rescousse et je parie que seuls quelques utilisateurs l'auront peut-être accidentellement désactivée puisque 99,99% des sites Web utilisent javascript et il est déjà activé par défaut dans tous les navigateurs modernes.

KMX
la source
J'ai vu des gens négliger complètement de se protéger contre l'injection de code, sans parler de le faire uniquement du côté client. Et aucune référence à l'injection de code n'est complète sans un lien vers ceci: xkcd.com/327 :)
Stewart
8

Vous pouvez faire une validation côté serveur et renvoyer un objet JSON avec les résultats de validation pour chaque champ, en gardant le Javascript du client au minimum (juste en affichant les résultats) et en ayant toujours une expérience conviviale sans avoir à vous répéter à la fois sur le client et le serveur.

Jonathan
la source
3
Convivial? Peut être. Presque instantané et onctueux? Probablement pas.
quadrupleslap
4

Le côté client doit utiliser une validation de base via les types d'entrée HTML5 et les attributs de modèle et comme ceux-ci ne sont utilisés que pour des améliorations progressives pour une meilleure expérience utilisateur (même s'ils ne sont pas pris en charge sur <IE9 et safari, mais nous ne comptons pas sur eux). Mais la validation principale devrait avoir lieu côté serveur.

adardesign
la source
"Mais la validation principale devrait avoir lieu côté serveur." Ne devrait pas, doit.
Stewart
2

JavaScript peut être modifié lors de l'exécution.

Je suggère un modèle de création d'une structure de validation sur le serveur et de partage avec le client.

Vous aurez besoin d'une logique de validation distincte aux deux extrémités, par exemple:

"required"attributs côté inputsclient

field.length > 0 du côté serveur.

Mais l'utilisation de la même spécification de validation éliminera une certaine redondance (et des erreurs) de la validation en miroir aux deux extrémités.

TaylorMac
la source
2

La validation des données côté client peut être utile pour une meilleure expérience utilisateur: par exemple, un utilisateur qui tape mal son adresse e-mail, ne doit pas attendre que sa demande soit traitée par un serveur distant pour connaître la faute de frappe qu'il a faite.

Néanmoins, comme un attaquant peut contourner la validation côté client (et peut même ne pas utiliser le navigateur du tout), la validation côté serveur est requise et doit être la véritable porte pour protéger votre backend des utilisateurs malveillants.

Billal Begueradj
la source
1

Je suis tombé sur un lien intéressant qui distingue les erreurs grossières, systématiques et aléatoires.

Client-Side validationconvient parfaitement pour éviter les erreurs grossières et aléatoires. Généralement une longueur maximale pour la texture et l'entrée. N'imitez pas la règle de validation côté serveur; fournissez votre propre règle de validation grossière (ex. 200 caractères côté client; côté nserveur dicté par une règle métier forte).

Server-side validationconvient parfaitement pour éviter les erreurs systématiques; il appliquera les règles commerciales.

Dans un projet dans lequel je suis impliqué, la validation se fait sur le serveur via des requêtes ajax. Sur le client, j'affiche les messages d'erreur en conséquence.

Lectures complémentaires: erreurs grossières, systématiques et aléatoires:

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

Roland
la source
-2

Si vous effectuez une validation légère, il est préférable de le faire sur le client. Cela économisera le trafic réseau, ce qui aidera votre serveur à mieux fonctionner. Si cela complique la validation qui implique d'extraire des données d'une base de données ou quelque chose, comme des mots de passe, il est préférable de le faire sur le serveur où les données peuvent être vérifiées en toute sécurité.

À M
la source
2
Ce que vous adorez n'est pas la meilleure idée. L'utilisateur peut toujours contourner la validation côté client et soumettre ce qu'il veut à la base de données.
kremuwa