Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Html Metaform дмитрий котеров

1,027 views

Published on

Published in: Technology, Design
  • Be the first to comment

Html Metaform дмитрий котеров

  1. 1. MetaForm: неизбыточная работа с метаданными HTML- форм Метаданные формы, защита от подделки, валидация Дмитрий Котеров, архитектор и главный разработчик MoiKrug.ru компания Яндекс [email_address]
  2. 2. Что такое метаданные? <ul><li>Данные </li></ul><ul><ul><li>то, что ввели </li></ul></ul><ul><li>array( &quot;lastname&quot; => &quot; Пупкин &quot;, &quot;gender&quot; => &quot;m&quot; ) </li></ul><ul><li>Метаданные </li></ul><ul><ul><li>&quot;данные о структуре данных&quot; </li></ul></ul><ul><li>array( &quot;lastname&quot; => array( &quot;type&quot; => &quot;text&quot;, &quot;caption&quot; => &quot; Фамилия &quot;, &quot;dbfield&quot; => &quot;p_lastname&quot; ), &quot;gender&quot; => array( &quot;type&quot; => &quot;single&quot; , &quot;dbfield&quot; => &quot;p_gender&quot; , &quot;elements&quot; => array( &quot;m&quot; = > &quot; Муж &quot;, &quot;f&quot; => &quot; Жен &quot;, ) ) ) </li></ul>Фамилия: <input type=&quot;text&quot; name=&quot;lastname&quot; /> Пол: <input type=&quot;radio&quot; name=&quot;gender&quot; value=&quot;m&quot; /> Муж <input type=&quot;radio&quot; name=&quot;gender&quot; value=&quot;f&quot; /> Жен
  3. 3. Типы полей с точки зрения метаданных <ul><li>Текст </li></ul><ul><ul><li><input type=&quot;text&quot;>, <input type=&quot;hidden&quot;>, <textarea> </li></ul></ul><ul><li>Файл (закачка) </li></ul><ul><ul><li><input type=&quot;file&quot;> </li></ul></ul><ul><li>Единичный выбор </li></ul><ul><ul><li><select></select> </li></ul></ul><ul><ul><li><input type=&quot;radio&quot;>… </li></ul></ul><ul><li>Множественный выбор (аналогично) </li></ul><ul><ul><li><select multiple></select> </li></ul></ul><ul><ul><li><input type=&quot;checkbox&quot;>… </li></ul></ul><ul><li>Действие </li></ul><ul><ul><li><input type=&quot;submit&quot;>, <input type=&quot;image&quot;> </li></ul></ul>
  4. 4. Web- или G UI- приложение <ul><li>Web- приложение </li></ul><ul><ul><li>&quot;Размазанность&quot; </li></ul></ul><ul><ul><li>Двойная валидация ( PHP, JS) </li></ul></ul><ul><ul><li>Нет доверия метаданным ( неявная структура POST) </li></ul></ul><ul><ul><li>Дублирование метаданных в дизайне и обработчике </li></ul></ul><ul><ul><li>Косвенный вызов обработчиков </li></ul></ul><ul><li>GUI- приложение </li></ul><ul><ul><li>Централизованная обработка </li></ul></ul><ul><ul><li>Непосредственная валидация </li></ul></ul><ul><ul><li>&quot;Доверие&quot; метаданным (все в рамках одной оконной формы) </li></ul></ul><ul><ul><li>Форма &quot;рисуется&quot; и обрабатывается в едином месте </li></ul></ul><ul><ul><li>Мгновенные обработчики кнопок </li></ul></ul>Рисовальщик формы Пользователь GUI- приложение: форма + обработчики событий Пользователь HTML POST errors Обработчик формы
  5. 5. &quot;Размазанность&quot; : неявные зависимости от метаданных <ul><li>Различные компоненты системы </li></ul><ul><ul><li>Структура БД </li></ul></ul><ul><ul><li>HTML- представление формы </li></ul></ul><ul><ul><li>Рисовальщик (код начального заполнения формы) </li></ul></ul><ul><ul><li>Обработчик (код приема данных и записи в БД) </li></ul></ul><ul><ul><li>Серверный валидатор ( PHP) </li></ul></ul><ul><ul><li>Клиентский валидатор (JS) </li></ul></ul><ul><li>Как их объединяют, чтобы обойти проблему </li></ul><ul><ul><li>Структура БД </li></ul></ul><ul><ul><li>HTML- представление формы + клиентский валидатор </li></ul></ul><ul><ul><li>Рисовальщик + обработчик + серверный валидатор </li></ul></ul>
  6. 6. Централизация метаданных <ul><li>Репозиторий метаданных </li></ul><ul><li>Подход MetaForm – похож на GUI -формы </li></ul>HTML + JS Рисовальщик + обработчик + валидатор Metadata HTML + Metadata <ul><li>Генератор по явно выделенным метаданным </li></ul><ul><ul><ul><li>сложность доработки </li></ul></ul></ul><ul><ul><ul><li>неуниверсальность </li></ul></ul></ul>Рисовальщик + модификатор + обработчик + валидатор БД БД
  7. 7. MetaForm: шаблон + метаданные <ul><li>Метаданные объединены с представлением (как в GUI) </li></ul><ul><li>Автоматическое извлечение метаданных </li></ul><ul><li>Использование возможностей HTML для привязки заглавия </li></ul><ul><li>Назначение валидаторов (серверных + клиентских) </li></ul><ul><li>Назначение произвольных мета-атрибутов </li></ul><ul><li>Отправка формы &quot;на себя&quot; </li></ul><ul><li>Обработка HTML &quot;на лету&quot;: </li></ul><ul><ul><li>Легкость адаптации старых проектов </li></ul></ul><ul><ul><li>Совместимость с любыми имеющимися framework- ами </li></ul></ul><ul><ul><li>Неизбыточность (&quot;а добавим-ка новое поле&quot;) </li></ul></ul><label for=&quot;l&quot;> Фамилия </label> : <input type=&quot;text&quot; name=&quot;lastname&quot; id=&quot;l&quot; meta:dbfield=&quot;p_lastname&quot; meta:validator=&quot;filled&quot; /> Пол: <label for=&quot;m&quot;> Муж </label> <input type=&quot;radio&quot; name=&quot;gender&quot; value=&quot;m&quot; id=&quot;m&quot; meta:dbfield=&quot;p_gender&quot; /> <label for=&quot;f&quot;> Жен </label> <input type=&quot;radio&quot; name=&quot;gender&quot; value=&quot;f&quot; id=&quot;f&quot;/>
  8. 8. MetaForm : традиционная обработка <ul><li>Обработка формы: </li></ul><ul><ul><li>распаковка метаданных </li></ul></ul><ul><ul><li>проверка цифровой подписи </li></ul></ul><ul><ul><li>валидация </li></ul></ul><ul><ul><li>сохранение сообщений об ошибках </li></ul></ul><ul><ul><li>сохранение сообщений в сессии </li></ul></ul><ul><ul><li>&quot;редирект на себя&quot; </li></ul></ul><ul><li>Подготовка метаданных </li></ul><ul><ul><li>извлечение метаданных из HTML формы, &quot;чистка&quot; формы </li></ul></ul><ul><ul><li>упаковка и цифровое подписывание метаданных </li></ul></ul><ul><ul><li>вставка метаданных в hidden- поле </li></ul></ul><ul><li>Отрисовка формы: </li></ul><ul><ul><li>вставка данных из $_POST ( FormPersister) </li></ul></ul><ul><ul><li>назначение клиентских валидаторов </li></ul></ul><ul><ul><li>привязка сообщений об ошибках к полям </li></ul></ul>switch ($m->process()) { // Простой показ формы. case &quot;INIT&quot; : $_POST = < достать из БД >; break; // Нажата кнопка. case &quot; имя_кнопки &quot; : $meta = $m->getMetadata(); < записать в БД >; < запомнить сообщ. успеха >; < редирект на себя >; break; // Произошла ошибка валидации } < показать ошибки и сообщения >; < заполнить поля из $_POST>; < подготовить метаданные >; < отрисовать форму >;
  9. 9. MetaForm : событийная обработка <ul><li>switch-case хорошо подходит при переводе старой системы на MetaForm </li></ul><ul><li>событийная модель удобна для построения CMF </li></ul>// Контроллер Page class Page { function init() { // Простой показ формы. $_POST = < достать из БД >; } function имя_кнопки() { // Нажата кнопка. $meta = $m->getMetadata(); < записать в БД >; < запомнить сообщ. успеха >; < редирект на себя >; } } <!-- Шаблон Page --> < показать ошибки и сообщения >; < заполнить поля из $_POST>; < подготовить метаданные >; < показать форму >;
  10. 10. Цифровая подпись метаданных <ul><li>Пусть metadata – упакованные метаданные: </li></ul><ul><ul><li>сервер хранит секретный ключ key </li></ul></ul><ul><ul><li>signed = metadata + &quot;-&quot; + md5( metadata + key ) </li></ul></ul><ul><ul><li>в hidden- поле записывается signed </li></ul></ul><ul><ul><li>проверка: md5(left(signed) + key ) == right(signed) </li></ul></ul><ul><li>Необходимо хранить key в секрете! </li></ul>
  11. 11. Защита от подделки форм <ul><li>Принудительная валидация: </li></ul><ul><ul><li>hidden- поля должны быть константными: <input type=&quot;hidden&quot; name=&quot;a&quot; value=&quot;b&quot;> => $_POST['a'] = 'b' </li></ul></ul><ul><ul><li>выбранный элемент из single или multiple должен содержаться в списке: <select name=&quot;s&quot;><option value=&quot;v&quot;> текст </select> => $_POST['s'] = 'v' </li></ul></ul><ul><ul><li>форма послана именно тому скрипту, который указан в ее атрибуте action : <form action=&quot;script&quot;> => REQUEST_URI ~ &quot;script&quot; </li></ul></ul><ul><ul><li>DB constraints никто не отменял! </li></ul></ul><ul><li>Отмена принудительной валидации </li></ul><ul><ul><li><input type=&quot;hidden&quot; meta:dynamic> => поле можно заполнять на JavaScript </li></ul></ul>
  12. 12. Защита: &quot;лишние&quot; поля формы <ul><li>Провоцирование неявной зависимости от метаданных </li></ul><ul><ul><li>Имеем форму: <input type=&quot;text&quot; name=&quot;person[firstname]&quot; /> <input type=&quot;text&quot; name=&quot;person[lastname]&quot; /> </li></ul></ul><ul><ul><li>Хакер добавляет &quot;лишнее&quot; поле: <input type=&quot;text&quot; name=&quot;person[firstname]&quot; /> <input type=&quot;text&quot; name=&quot;person[lastname]&quot; /> <input type=&quot;hidden&quot; name=&quot;person[is_admin]&quot; value=&quot;1&quot; /> </li></ul></ul><ul><ul><li>Результат: изменение неожиданного поля </li></ul></ul><ul><li>MetaForm: неизвестные поля считаются подделкой </li></ul>
  13. 13. Неизбыточная валидация <ul><li>Привязка валидаторов <input meta:validator=&quot;filled email&quot;> </li></ul><ul><li>В полю привязано имя валидатора : </li></ul><ul><ul><li>вызов валидатора на стороне сервера ( PHP) function validator_ название ($value, $metadata) </li></ul></ul><ul><ul><li>автопривязка валидатора на стороне клиента ( JavaScript) validator_ название = function(value, metadata) </li></ul></ul><ul><li>Привязка нескольких валидаторов <input meta:validator=&quot;filled email&quot;> </li></ul><ul><li>Валидаторы должны быть ортогональными </li></ul><ul><li>Передача параметров валидаторам Пароль: <input type=&quot;password&quot; name=&quot;pass&quot; meta:validator=&quot;password_match&quot; meta:match_field=&quot;confirm&quot; /> Еще раз : <input type=&quot;password&quot; name=&quot;confirm&quot; /> </li></ul>
  14. 14. Привязка сообщений об ошибках <ul><li>Ошибка валидации привязана к полю формы </li></ul><ul><ul><li>Метаданные содержат ID (координаты) всех полей </li></ul></ul><ul><ul><li>Привязка ошибки к элементу на JavaScript (&quot;модель светофора&quot;) </li></ul></ul><ul><ul><li>Фокус на ошибочном элементе </li></ul></ul><ul><li>Извлечение текста ошибки по имени валидатора (языковые константы ) </li></ul><ul><ul><li>'validator_email' => ' Поле &quot;%s&quot; должно содержать корректный E-mail!' </li></ul></ul><ul><ul><li>Подстановка имен полей ( sprintf) </li></ul></ul>
  15. 15. Резюме <ul><li>Плюсы подхода MetaForm: </li></ul><ul><ul><li>Родство с GUI- программированием </li></ul></ul><ul><ul><li>Неизбыточность </li></ul></ul><ul><ul><li>Прозрачность для любого framework- а </li></ul></ul><ul><ul><li>Легкость адаптации существующих проектов </li></ul></ul><ul><ul><li>Прозрачность для HTML- верстальщика </li></ul></ul><ul><li>Минусы: </li></ul><ul><ul><li>Смешение логики метаданных и логики представления ( характерно и для GUI) </li></ul></ul>
  16. 16. Приходите к нам работать! <ul><li>МойКруг.ру теперь – сервис Яндекса </li></ul><ul><li>Мы расширяем свою команду! </li></ul><ul><li>Открыты вакансии для: </li></ul><ul><ul><li>верстальщиков со знанием Smarty </li></ul></ul><ul><ul><li>отличных PHP- программистов </li></ul></ul><ul><ul><li>опытных БД-разработчиков ( PostgreSQL, Oracle) </li></ul></ul><ul><ul><li>JavaScript- программистов </li></ul></ul>Ждем Ваши резюме на http://moikrug.ru/hire/

×