Validation de la saisie des données - Où? Combien? [fermé]


28

La validation de la saisie des données a toujours été une lutte interne pour moi.

Sur le point d'ajouter un véritable cadre et code de sécurité à notre projet de réécriture d'applications héritées (qui jusqu'à présent conserve à peu près le code de sécurité hérité de la carte fort et la validation des données), je me demande à nouveau combien dois-je valider, où, etc.

Au cours de mes 5 années en tant que développeur Java professionnel, j'ai créé et affiné mes règles personnelles pour la validation de la saisie des données et les mesures de sécurité. Comme j'aime améliorer mes méthodes, j'aimerais que certains entendent des idées de vous. Les règles et procédures générales sont correctes, et celles spécifiques à Java aussi.

Résumées, voici mes directives (exposées sur un style d'application Web à 3 niveaux), avec de brèves explications:

  • Côté client 1er niveau (navigateur): validation minimale, seules les règles invariables (champ email obligatoire, doivent sélectionner un élément, etc.); utilisation d'une validation supplémentaire comme "entre 6 et 20 caractères" moins fréquente, car cela augmente le travail de maintenance sur les modifications (peut être ajouté une fois que le code d'entreprise est stable);

  • Côté serveur 1er niveau (gestion des communications web, "contrôleurs"): je n'ai pas de règle pour celui-ci, mais je pense que seules les erreurs de manipulation de données et d'assemblage / analyse doivent être gérées ici (le champ anniversaire n'est pas une date valide); ajouter ici une validation supplémentaire en fait facilement un processus vraiment ennuyeux;

  • 2e niveau (couche métier): validation solide comme le roc, rien de moins; format de données d'entrée, plages, valeurs, vérification de l'état interne si la méthode ne peut pas être appelée à tout moment, rôles / autorisations utilisateur, etc. utilisez le moins de données d'entrée utilisateur possible, récupérez-les à nouveau dans la base de données si nécessaire; si nous considérons également les données de base de données récupérées comme des entrées, je ne les validerais que si certaines données spécifiques sont connues pour ne pas être suffisamment fiables ou corrompues sur la base de données - le typage fort fait la plupart du travail ici, à mon humble avis;

  • 3ème niveau (couche de données / DAL / DAO): jamais pensé que beaucoup de validation était nécessaire ici, car seule la couche métier est censée accéder aux données (valider peut-être dans certains cas comme "param2 ne doit pas être nul si param1 est vrai"); notez cependant que lorsque je veux dire "ici", je veux dire "code qui accède à la base de données" ou "méthodes d'exécution SQL", la base de données elle-même est complètement le contraire;

  • la base de données (modèle de données): doit être aussi bien pensée, solide et auto-exécutoire que pour éviter autant que possible les données incorrectes et corrompues sur la base de données, avec de bonnes clés primaires, clés étrangères, contraintes, type de données / longueur / taille / precision et ainsi de suite - je laisse de côté les déclencheurs, car ils ont leur propre discussion privée.

Je sais que la validation précoce des données est agréable et performante, mais la validation répétée des données est un processus ennuyeux, et j'avoue que la validation des données elle-même est assez ennuyeuse. C'est pourquoi tant de codeurs l'ignorent ou le font à mi-chemin. De plus, chaque validation dupliquée est un bug possible si elles ne sont pas synchronisées en permanence. Ce sont les principales raisons pour lesquelles je préfère aujourd'hui laisser la plupart des validations à la couche métier, au détriment du temps, de la bande passante et du processeur, les exceptions étant gérées au cas par cas.

Alors, qu'est-ce que tu en penses? Opinions opposées? Avez-vous d'autres procédures? Une référence à un tel sujet? Toute contribution est valable.

Remarque: si vous envisagez la façon de faire Java, notre application est basée sur Spring avec Spring MVC et MyBatis (les performances et le mauvais modèle de base de données excluent les solutions ORM); Je prévois d'ajouter Spring Security en tant que notre fournisseur de sécurité plus JSR 303 (Hibernate Validator?)

Merci!


Edit: quelques précisions supplémentaires sur la 3ème couche.


Mon conseil est d'étudier le fonctionnement d'Hibernate Validator. Je n'ai pas trouvé JSR 303 utile, car la validation entre en action pendant la persistance, alors que certaines de mes règles devaient être appliquées bien avant la persistance, car j'avais des règles métier qui reposaient sur une validation de base. À mon avis, cela fonctionne pour un modèle très fermé; peut-être que je ne l'utilisais pas correctement, mais je n'ai jamais trouvé personne ayant des expériences différentes des miennes.
Vineet Reynolds

@Vineet Reynolds Je l'ai déjà utilisé pour la validation de formulaire avec Spring MVC, c'est vraiment une excellente combinaison. J'obtiens une validation côté serveur avec des messages à grain fin avec peu ou pas d'effort, une erreur appropriée s'affiche pour l'utilisateur. Je dois encore le tester entièrement sur des objets côté serveur, pas sûr des avantages. Jetez un oeil à cet exemple de message, c'est comme ça que je l'ai utilisé: codemunchies.com/2010/07/…
mdrg

2
mettre trop de validation. EveryWhere damn ces entrées utilisateur @ #! ! @@!
Chani

Réponses:


17

Votre validation doit être cohérente. Donc, si un utilisateur entre des données sur le formulaire Web qui sont déterminées comme valides, elles ne devraient pas être rejetées par la couche de base de données en raison de certains critères que vous n'avez pas mis en œuvre côté client.

En tant qu'utilisateur, rien ne serait plus ennuyeux que d'entrer une page pleine de données apparemment correctement seulement pour être informé après un aller-retour significatif dans la base de données que quelque chose n'allait pas. Cela serait particulièrement vrai si j'avais déclenché une validation client dans le processus.

Vous devez avoir la validation à différents niveaux car vous les exposez et vous n'avez potentiellement aucun contrôle sur qui les appelle. Vous devez donc prendre des dispositions (dans la mesure du possible) pour que votre validation soit définie en un seul endroit et appelée d'où elle est nécessaire. La façon dont cela est organisé dépendra de votre langage et de votre cadre. Dans Silverlight (par exemple), vous pouvez le définir côté serveur et avec des attributs appropriés, il sera copié côté client pour y être utilisé.


2
+1 Absolument. J'allais dire la même chose à propos d'ASP.NET MVC, mais vous m'avez battu. :) Vraiment, nous avons seulement besoin d'une validation sur place pour nous assurer qu'un système reste dans un état valide. Le reste de la validation, comme le côté client, vise à améliorer la convivialité et le temps perdu pour l'utilisateur, ce qui devrait être l'objectif principal. La cohérence est la clé.
Ryan Hayes

2
À propos du "aller-retour", je ne vois aucun problème tant que la page est rechargée avec des messages d'erreur appropriés et tous les champs remplis avec ce que vous avez tapé avant (la plupart des interfaces ne répondent pas à ce dernier détail). Si cela prend trop de temps pour récupérer les erreurs, alors c'est un candidat pour une validation supplémentaire côté client.
mdrg

Et bien sûr, si la validation peut être répliquée facilement dans l'application, il n'y a aucune raison de gaspiller cela. Côté serveur, c'est facile, mais côté client, sans ces outils de validation tels que celui que vous avez mentionné, cela devient très frustrant (c'est-à-dire: écrire beaucoup de code de validation JS, tout comme celui que vous avez écrit sur le serveur) .
mdrg

10

Dans un système relationnel, je le vois comme une approche à trois niveaux. Chaque couche est contrainte par celles ci-dessous:

  • Présentation / UI
    • validation d'entrée simple
    • ne continuez pas si l'entrée est au mauvais format
    • "gate" les demandes des clients au serveur pour réduire les allers-retours, pour une meilleure convivialité et une réduction de la bande passante / temps
  • Logique
    • logique métier et autorisation
    • ne laissez pas les utilisateurs faire des choses qu'ils ne sont pas autorisés à faire
    • gérer les propriétés "dérivées" et les déclarer ici (choses qui seraient dénormalisées dans la base de données)
  • Les données
    • la couche essentielle d'intégrité des données
    • refuser absolument de stocker toute ordure
    • la base de données elle-même applique les formats de données (int, date, etc.)
    • utiliser des contraintes de base de données pour garantir de bonnes relations

La réponse idéale à cela serait un système qui vous permet de définir les contraintes sur les trois couches en un seul endroit. Cela impliquerait une certaine génération de code pour SQL et au moins une validation basée sur les données pour le client et le serveur.

Je ne sais pas s'il y a une solution miracle ici ... mais puisque vous êtes sur la JVM, je suggère de regarder Rhino pour au moins partager le code de validation JavaScript entre le client et le serveur. N'écrivez pas votre validation d'entrée deux fois.


Je vais jeter un œil à Rhino. S'il peut s'intégrer d'une manière ou d'une autre à la validation de formulaire Spring MVC, tant mieux.
mdrg

8

• 3ème niveau (couche de données / DAL / DAO): jamais pensé que beaucoup de validation est nécessaire ici, car seule la couche métier est censée accéder aux données (valider peut-être dans certains cas comme "param2 ne doit pas être nul si param1 est vrai") .

C'est tellement faux. L'endroit le plus important pour avoir la validation est dans la base de données elle-même. Les données sont presque toujours affectées par plus que l'application (même si vous pensez que ce ne sera pas le cas) et il est irresponsable au mieux de ne pas placer les contrôles appropriés dans la base de données. Il y a plus de perte d'intégrité des données d'une décision de ne pas le faire que tout autre facteur. L'intégrité des données est essentielle à l'utilisation à long terme de la base de données. Je n'ai jamais vu de base de données n'ayant pas réussi à appliquer des règles d'intégrité au niveau de la base de données contenant de bonnes données (et j'ai vu les données dans des milliers de bases de données).

Il le dit mieux que moi: http://softarch.97things.oreilly.com/wiki/index.php/Database_as_a_Fortress


Je suis d'accord sur le tout dernier morceau avec cet article, je suppose que je ne me suis pas précisé sur cette partie. J'ai mis à jour la question avec plus de détails. Merci!
mdrg

2

Tout ce qui précède suppose que les développeurs et les mainteneurs sont parfaits et écrivent un code parfait qui fonctionne toujours parfaitement. Les futures versions du logiciel connaissent toutes les hypothèses que vous avez formulées et jamais documentées, ainsi que les utilisateurs et les pirates informatiques qui introduisent des données dans le système d'une manière que vous n'auriez jamais imaginée.

Bien sûr, trop de validation est une mauvaise chose, mais en supposant que les programmes, les réseaux et les systèmes d'exploitation sont parfaits, les pirates ne passeront pas par votre pare-feu, les DBA ne "modifieront" pas manuellement la base de données est probablement pire.

Tracez des cercles de délimitation autour des objets, identifiez les modes de défaillance contre lesquels ils protègent et implémentez un niveau de vérification approprié pour cette limite. Par exemple, votre base de données ne devrait jamais voir de données invalides, mais comment cela pourrait-il arriver et que se passerait-il si cela se produisait? Qui est votre utilisateur, quel est le coût de l'échec?

Étudiez les modèles de sécurité du monde physique, la sécurité devrait être en couches, comme un oignon. Un mur épais est considéré comme une mauvaise sécurité. La validation des données doit être considérée de la même manière.


1

Deux courtes règles générales de validation:

Si vous allez appeler quelque chose qui ne garantit pas qu'il renverra quelque chose (erreur, exception) pour vous informer d'une entrée non valide d'une manière que vous pouvez transmettre à votre appelant, validez-la.

Si vous allez faire autre chose avec les données (prendre des décisions, faire des calculs, les stocker, etc.), validez-les.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.