Ну вот, вы ожидаете, что пришел например id и делаете запрос select * from `account` where `id` = 1;
а пришел не id, а ` = 1; select 1; --
Тогда вы сгенеририуете такой sql: select * from `account` where `id` = 1; select 1; -- ` = 1
Он выполнится без exception. Вместо select 1 можно указать что угодно.
Поэтому стоит сравнивать названия колонок со схемой, да и условия >=, < и т.д. тоже валидировать.
В библиотеке реализовано чтение данных. Запись можно реализовать самому. В целях POData автор форка ставил реализацию INSERT, UPDATE, DELETE, но до сих пор это не сделано. В принципе, при реализации можно и учесть моменты с конкурентными запросами, хотя это не всегда надо. Скажите для примера, где это хорошо учтено?
Можно пример? Мне приходит на ум только сопоставление названий со схемой базы. Но в любом случае для этого надо сперва распарсить условие. Либо передавать условие от клиента сразу в виде дерева. Помимо этого и операторы тоже надо валидировать. На мой взгляд в итоге получается громоздко и это надо писать самому. Либо можно взять готовое и использовать OData как вариант.
В настоящий момент в POData добавление не реализовано, только GET. Если мне понадобится в процессе добавление, редактирование, удаление, буду реализовывать. Насчет конкурентно добавлять уточните, пожалуйста, что имеете ввиду — вариант обернуть запросы в транзакцию подходит?
Насчет 1, дело в том, что валидировать надо не только значения, но и названия колонок, по которым выполняется фильтрация, если это название получено с клеинта.
По поводу 2, замечание совершенно замечательное. Такие вещи можно обрабатывать в обертке над QueryProvider, делать дополнительную проверку для нужных таблиц, чтобы было такое-то условие. Это может быть не всегда просто в реализации, но делать это действительно стоит.
Само слово weight, полученное с клиента надо тоже валидировать, я об этом, не о значении 100.
пришлось дописать в разы больше
Ну не в разы, но много писать самому пришлось, я об этом упомянул. Но надо учесть, что я как-то уже реализовывал универсальный механизм и видел, как коллеги делали универсальный механизм для фильтрации данных — там кода было куда больше. А если не делать универсальный механизм, то придется много писать кода под конкретные случаи, что будет путаться с бизнес-логикой, это труднее на мой взгляд поддерживать.
GridView штука хорошая, но и в ней к сожалению есть ограничения. OData дает больше возможностей, меня это и привлекает. Не панацея, но инструмент на мой взгляд действительно достойный.
В случае с OData не надо ничего писать для извлечения данных, если действовать как описано в статье. Yii2 дает готовый инструмент только на уровне контроллеров, при этом надо самому делать валидацию, защиту от SQL инъекций. Например, так просто нельзя ведь написать, 'weight<100'. Надо как минимум проверить, что пришедший с клиента weight это колонка, а не что-то вроде '; drop table ... --'.
POData дает готовый инструмент не только на уровне контроллеров, но и сам делает валидацию, помогает в извлечении данных. А если использовать стандартный грид с поддержкой OData (типа OpenUI5), то о том, как будет выглядеть GET запрос, можно даже не заботиться, грид сформирует запрос за вас.
Я пользовался Yii2 RESTful. Это отличный инструмент. Но столкнулся с тем, что приходится делать вещи, которые можно было бы не делать. Например, понадобилась произвольная фильтрация. В OData можно сделать условие типа такого
$filter=((weight ge 100 or weight le 10) and price le 15)
И оно будет работать без какого-либо дополнительного программирования.
Не смущает, на этот случай был придуман велосипед — переданные параметры сортируются в алфавитном порядке. В WSDL тоже параметры описаны в алфавитном порядке. Но, как оказалось, на этот случай есть готовое простое решение — вместо sequence можно использовать all в WSDL.
Некоторые ограничения на формат есть, но по практике скажу, что трудностей это не создает.
Не сказал бы, что слишком сложно. По сути, за валидацию отвечает несколько строк. Если упрощенно, то примерно так:
$validator = new \DOMDocument( '1.0', 'UTF-8' );
$validator->loadXML( $xml );
if (!$validator->schemaValidateSource($xsd)) {
...
}
Т.е. в PHP для этого готовые инструменты есть.
Или громоздко описания выглядят? Ну, возможно. Меня не напрягает, думаю, дело привычки.
Автоматические генераторы есть, и тут уже больше философский вопрос, что первично — документация или код. Мне близок подход, когда сперва составляется осмысленная документация.
Методы для работы с \DOMDocument, кстати, вынесены в отдельную библиотеку, или скорее даже фреймворк, его у нас соседняя команда сделала, но он к сожалению не публичный.
У нас на PHP проекте API описано на WSDL, это описание работает и для первичной валидации. Документацию получаем с помощью XSLT преобразования WSDL-ки. Подход хорошо себя зарекомендовал. Но приведенный в статье набор инструментов вокруг RAML впечатляет.
idи делаете запросselect * from `account` where `id` = 1;а пришел не
id, а` = 1; select 1; --Тогда вы сгенеририуете такой sql:
select * from `account` where `id` = 1; select 1; -- ` = 1Он выполнится без exception. Вместо select 1 можно указать что угодно.
Поэтому стоит сравнивать названия колонок со схемой, да и условия >=, < и т.д. тоже валидировать.
where:where`=1; drop table ... --?По поводу 2, замечание совершенно замечательное. Такие вещи можно обрабатывать в обертке над QueryProvider, делать дополнительную проверку для нужных таблиц, чтобы было такое-то условие. Это может быть не всегда просто в реализации, но делать это действительно стоит.
Само слово weight, полученное с клиента надо тоже валидировать, я об этом, не о значении 100.
Ну не в разы, но много писать самому пришлось, я об этом упомянул. Но надо учесть, что я как-то уже реализовывал универсальный механизм и видел, как коллеги делали универсальный механизм для фильтрации данных — там кода было куда больше. А если не делать универсальный механизм, то придется много писать кода под конкретные случаи, что будет путаться с бизнес-логикой, это труднее на мой взгляд поддерживать.
GridView штука хорошая, но и в ней к сожалению есть ограничения. OData дает больше возможностей, меня это и привлекает. Не панацея, но инструмент на мой взгляд действительно достойный.
'weight<100'. Надо как минимум проверить, что пришедший с клиентаweightэто колонка, а не что-то вроде'; drop table ... --'.POData дает готовый инструмент не только на уровне контроллеров, но и сам делает валидацию, помогает в извлечении данных. А если использовать стандартный грид с поддержкой OData (типа OpenUI5), то о том, как будет выглядеть GET запрос, можно даже не заботиться, грид сформирует запрос за вас.
$filter=((weight ge 100 or weight le 10) and price le 15)И оно будет работать без какого-либо дополнительного программирования.
Вирусбери.Клиент
Некоторые ограничения на формат есть, но по практике скажу, что трудностей это не создает.
Т.е. в PHP для этого готовые инструменты есть.
Или громоздко описания выглядят? Ну, возможно. Меня не напрягает, думаю, дело привычки.
Автоматические генераторы есть, и тут уже больше философский вопрос, что первично — документация или код. Мне близок подход, когда сперва составляется осмысленная документация.
Пример части с документацией: