A validação de entrada de dados sempre foi uma luta interna para mim.
À beira de adicionar uma estrutura e um código de segurança reais ao nosso projeto de reescrita de aplicativos herdados (que até agora mantém praticamente o código de segurança herdado e a validação de dados), estou pensando novamente sobre quanto devo validar, onde etc.
Nos meus 5 anos como desenvolvedor profissional de Java, criei e refinei minhas regras pessoais para validação de entrada de dados e medidas de segurança. Como gosto de melhorar meus métodos, alguns gostariam de ouvir algumas idéias de vocês. Regras e procedimentos gerais são bons e específicos de Java também.
Resumidas, estas são minhas diretrizes (expostas em um estilo de aplicativo da web de três camadas), com breves explicações:
Lado do cliente da 1ª camada (navegador): validação mínima, apenas regras invariáveis (campo obrigatório de e-mail, deve selecionar um item e similares); uso de validação adicional como "entre 6 e 20 caracteres" menos frequente, pois isso aumenta o trabalho de manutenção nas alterações (pode ser adicionado quando o código comercial estiver estável);
Lado do servidor de 1ª camada (manipulação de comunicação na web, "controladores"): não tenho uma regra para esta, mas acredito que apenas os erros de manipulação de dados e montagem / análise devem ser tratados aqui (o campo de aniversário não é uma data válida); adicionar validação adicional aqui facilmente o torna um processo realmente chato;
2º nível (camada de negócios): validação sólida, nada menos; formato de dados de entrada, intervalos, valores, verificação interna do estado se o método não pode ser chamado a qualquer momento, funções / permissões do usuário e assim por diante; use o mínimo possível de dados de entrada do usuário, recupere-os novamente do banco de dados, se necessário; se considerarmos os dados recuperados do banco de dados como entrada também, eu apenas os validaria se alguns dados específicos forem confiáveis ou corrompidos o suficiente no banco de dados - a digitação forte faz a maior parte do trabalho aqui, IMHO;
3ª camada (camada de dados / DAL / DAO): nunca se acreditou que muita validação fosse necessária aqui, pois apenas a camada de negócios deveria acessar os dados (valide talvez em alguns casos como "param2 não deva ser nulo se param1 for verdadeiro"); observe, no entanto, que quando eu quero dizer "aqui", quero dizer "código que acessa o banco de dados" ou "métodos de execução SQL", o próprio banco de dados é completamente o oposto;
o banco de dados (modelo de dados): precisa ser tão bem pensado, forte e auto-impositivo quanto evitar dados incorretos e corrompidos no banco de dados, tanto quanto possível, com boas chaves primárias, chaves estrangeiras, restrições, tipo / comprimento / tamanho de dados / precision e assim por diante - estou deixando os gatilhos fora disso, pois eles têm sua própria discussão particular.
Sei que a validação antecipada de dados é agradável e em termos de desempenho, mas a validação repetida é um processo chato e admito que a validação de dados em si é bastante irritante. É por isso que muitos codificadores pulam ou fazem isso até a metade. Além disso, toda validação duplicada é um bug possível se não estiverem sincronizadas o tempo todo. Esses são os principais motivos pelos quais hoje em dia prefiro deixar a maioria das validações até a camada de negócios, em detrimento do tempo, largura de banda e CPU, exceções tratadas caso a caso.
Então, o que você pensa sobre isso? Opiniões opostas? Você tem outros procedimentos? Uma referência a esse tópico? Qualquer contribuição é válida.
Nota: se você está pensando na maneira Java de fazer as coisas, nosso aplicativo é baseado em Spring com Spring MVC e MyBatis (desempenho e modelo de banco de dados incorreto excluem as soluções ORM); Pretendo adicionar o Spring Security como nosso provedor de segurança mais o JSR 303 (Hibernate Validator?)
Obrigado!
Editar: algum esclarecimento extra na 3ª camada.