Где вы делаете свою проверку? модель, контроллер или вид
Куда вы помещаете проверку ввода пользователя в приложении веб-формы?
- Вид: клиентская часть JavaScript
- Контроллер: язык на стороне сервера (C#...)
- Модель: база данных (хранимые процедуры или зависимости)
Я думаю, что для каждого уровня требуется проверка:
- Пользователь ввел вменяемое значение
- являются фактическими датами, являются фактическими числами...
- Выполните все проверки в 1. снова плюс проверки на вредоносные атаки (IE XSS или SQL-инъекция)
- Проверки, выполненные в 1., в основном, чтобы избежать обхода сервера в случае ошибки пользователя.
- Так как они сделаны на стороне клиента в javascript, вы не можете поверить, что они были запущены. Повторная проверка этих значений остановит некоторые злонамеренные атаки.
- Встречаются ли зависимости (т. Е. Добавил ли пользователь комментарий к правильному вопросу)
- Хороший интерфейс делает их очень трудно нарушать. Если что-то здесь попало, что-то пошло не так.
[вдохновленный этим ответом]
10 ответов
Я проверяю все уровни, но хотел бы отметить проверочный трюк, который я использую.
Я проверяю на уровне базы данных, правильные ограничения вашей модели обеспечат автоматическую проверку целостности данных.
Это искусство, которое кажется потерянным для большинства веб-программистов.
Валидация в модели, опционально автоматизированные подпрограммы в пользовательском интерфейсе, которые берут свои подсказки из модели и улучшают взаимодействие с пользователем.
Под автоматическими процедурами я подразумеваю, что в пользовательском интерфейсе не должно быть кода проверки каждой модели. Если у вас есть библиотека методов проверки, таких как RoR (в которой есть методы, такие как validates_presence_of:username), контроллер или представление должны иметь возможность читать их и применять эквивалентные методы javascript (или любые другие удобные).
Это означает, что вам придется дублировать полную библиотеку валидации в пользовательском интерфейсе или, по крайней мере, предоставить отображение, если вы используете уже существующую. Но как только это будет сделано, вам не придется писать логику проверки вне модели.
Проверка может быть выполнена на всех уровнях.
Проверка ввода из веб-формы (все строки, приведение к нужным типам и т. Д.) Отличается от проверки ввода из веб-службы или файла XML и т. Д. У каждого есть свои особые случаи. Конечно, вы можете создать вспомогательный класс Validator, тем самым извлекая из него валидацию и позволяя ей делиться представлениями.
Затем у вас есть проверка уровня DAO - достаточно ли в модели данных для сохранения (чтобы соответствовать ненулевым ограничениям и т. Д.) И так далее. Вы даже можете иметь проверочные ограничения в базе данных (это статус в ('N', 'A', 'S', 'D') и т. Д.).
Проверка должна быть выполнена в контроллере - это единственное место, которое обеспечивает безопасность и реакцию.
Проверка должна быть выполнена в виде - это точка соприкосновения и обеспечит лучшее UE и сэкономит вашему серверу дополнительную работу.
Проверка будет проводиться на модели - но только для определенного базового уровня проверок. Базы данных должны всегда отражать соответствующие ограничения, но неэффективно, чтобы это означало реальную проверку, и при этом не всегда возможно, чтобы база данных определила допустимый ввод с простыми ограничениями.
Это интересно. Долгое время я выполнял всю проверку в модели, прямо над тем, что я бы назвал DAL (уровень доступа к данным). Мои модели обычно создаются по образцу после шлюза табличных данных с DAL, обеспечивающим абстракцию и низкоуровневый API.
В сторону TDG я бы реализовал бизнес-логику и проверки, такие как:
- Имя пользователя пусто
- Имя пользователя> 30 символов
- Если запись не существует, верните ошибку
По мере усложнения моего приложения я начал понимать, что большая часть проверки может быть выполнена на стороне клиента с использованием JavaScript. Поэтому я реорганизовал большую часть логики проверки в JS и очистил свои модели.
Затем я понял, что проверка на стороне сервера (а не фильтрация / экранирование - что я считаю другим) должна выполняться, вероятно, и на сервере, и только на стороне клиента, как глазурь на торте.
Таким образом, логика валидации вернулась, когда я снова осознала, что, вероятно, существует определенная разница между валидацией / утверждением INPUT и бизнес-правилами / логикой.
В принципе, если это можно сделать на стороне клиента приложения (используя JS), я считаю это проверкой INPUT... если это ДОЛЖНО быть сделано моделью (эта запись уже существует и т. Д.?), То я бы посчитал, что бизнес логика. Что сбивает с толку, так это то, что они оба защищают целостность модели данных.
Если вы не проверяете длину имени пользователя, что может помешать людям создать одно-символьное имя пользователя?
Я до сих пор не совсем решил, куда поместить эту логику дальше, я думаю, что это действительно зависит от того, что вы предпочитаете больше, тонких контроллеров, тяжелых моделей или наоборот...
Контроллеры в моем случае имеют тенденцию быть в большей степени ориентированными на приложения, в то время как модели, созданные тщательно, я часто могу использовать в "других" проектах, а не только внутри, поэтому я предпочитаю держать модели легкими и контроллеры на более тяжелой стороне.
То, что заставляет вас двигаться в любом направлении, - это действительно личное мнение, требования, опыт и т. Д.
Интересная тема:)
Вся проверка должна происходить как минимум один раз, и это должно быть на среднем уровне, будь то в ваших ценностных объектах (в смысле DDD, не путать с DTO) или через бизнес-объект самой сущности. Проверка на стороне клиента может выполняться для улучшения взаимодействия с пользователем. Я склонен не выполнять проверку на стороне клиента, потому что я могу просто сразу показать все, что неправильно в форме, но это только мое личное предпочтение. Проверка базы данных может происходить для обеспечения целостности данных в случае, если вы испортили логику в средний уровень или что-то закончилось.
Поскольку большая часть проверок зависит от бизнес-правил, я выполняю проверку на бизнес-уровне как сторонние инструментальные классы. Существуют другие типы проверок, такие как пользовательский ввод, в то время как это должно быть сделано в контроллере, но вы можете также инкапсулировать эти правила проверки в сторонние классы. Действительно, это зависит от того, что проверять.
Проверки на стороне клиента являются второстепенными, они просто созданы для облегченной проверки ввода, но проверка на стороне сервера требуется всегда. Вы никогда не можете доверять пользовательскому вводу;)
В.NET есть хорошие элементы управления для создания проверок, но бизнес-уровню всегда нужен лучший подход для проверки данных, и этих элементов управления недостаточно для этой задачи.
Хм, не уверен. Я бы сказал, что контроллер, пока я не прочитал эту статью о: тощие контроллеры, толстые модели
Я делаю это только в представлении и контроллере, база данных реализует некоторые из них в соответствии с вашими типами данных и так далее, но я бы предпочел, чтобы это не зашло так далеко, пока я не уловил ошибку.
Вы в значительной степени ответили на свой собственный вопрос, однако важно знать, что вы никогда не можете доверять представлению, хотя это самый простой способ обратной связи с пользователем, поэтому вам нужно провести санитарную очистку как минимум еще на одном уровне.
Простая проверка ввода в представлении. Полная проверка в модели. Причина? Если вы изменили технологию представления, и проверка выполняется в представлении / контроллере, вам придется переписать проверку для нового представления. Это может привести к ошибкам. Поместите это в модель, и это используется всеми взглядами...
Но, как я уже сказал, простая проверка с точки зрения скорости и легкости.