Pull to refresh
47
0
Николай @mnv

CTO

Send message
Ну вот, вы ожидаете, что пришел например 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, но до сих пор это не сделано. В принципе, при реализации можно и учесть моменты с конкурентными запросами, хотя это не всегда надо. Скажите для примера, где это хорошо учтено?
а если с клиента пришло вместо where:
where`=1; drop table ... --?
Можно пример? Мне приходит на ум только сопоставление названий со схемой базы. Но в любом случае для этого надо сперва распарсить условие. Либо передавать условие от клиента сразу в виде дерева. Помимо этого и операторы тоже надо валидировать. На мой взгляд в итоге получается громоздко и это надо писать самому. Либо можно взять готовое и использовать OData как вариант.
В настоящий момент в POData добавление не реализовано, только GET. Если мне понадобится в процессе добавление, редактирование, удаление, буду реализовывать. Насчет конкурентно добавлять уточните, пожалуйста, что имеете ввиду — вариант обернуть запросы в транзакцию подходит?
Насчет 1, дело в том, что валидировать надо не только значения, но и названия колонок, по которым выполняется фильтрация, если это название получено с клеинта.
По поводу 2, замечание совершенно замечательное. Такие вещи можно обрабатывать в обертке над QueryProvider, делать дополнительную проверку для нужных таблиц, чтобы было такое-то условие. Это может быть не всегда просто в реализации, но делать это действительно стоит.
'weight<:weight'

Само слово 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.
Некоторые ограничения на формат есть, но по практике скажу, что трудностей это не создает.
Бывает и такое. В этом случае просто JSON преобразуем в XML и направляем на валидацию
Не сказал бы, что слишком сложно. По сути, за валидацию отвечает несколько строк. Если упрощенно, то примерно так:
$validator = new \DOMDocument( '1.0', 'UTF-8' );
$validator->loadXML( $xml );
if (!$validator->schemaValidateSource($xsd)) {
  ...
}

Т.е. в PHP для этого готовые инструменты есть.
Или громоздко описания выглядят? Ну, возможно. Меня не напрягает, думаю, дело привычки.
Автоматические генераторы есть, и тут уже больше философский вопрос, что первично — документация или код. Мне близок подход, когда сперва составляется осмысленная документация.
Методы для работы с \DOMDocument, кстати, вынесены в отдельную библиотеку, или скорее даже фреймворк, его у нас соседняя команда сделала, но он к сожалению не публичный.
Фрейморк-то Yii2, но он тут ни при чем. Работа с WSDL через \DOMDocument.
Пример, входные параметры:
 <xs:element name="accountRequestData">
    <xs:complexType>
        <xs:sequence>
            <xs:annotation>
                <xs:documentation source="id" xml:lang="ru">Идентификатор записи</xs:documentation>
                <xs:documentation source="inn" xml:lang="ru">ИНН</xs:documentation>
                <xs:documentation source="is_active" xml:lang="ru">Счет активен</xs:documentation>
                <xs:documentation source="user_id" xml:lang="ru">Пользователь</xs:documentation>
            </xs:annotation>
            <xs:element name="id" type="xs:int" />
            <xs:element name="inn" type="xs:string" minOccurs="0" />
            <xs:element name="is_active" type="ns:BOOL" />
            <xs:element name="user_id" type="xs:int" />
        </xs:sequence>
    </xs:complexType>
</xs:element>


Пример части с документацией:
<operation name="methodAccount">
    <documentation type="map">
        <name>Вставка и изменение счета</name>
        <status>works</status>
        <speed_level>fast</speed_level>
        <quota_per_second>20</quota_per_second>
        <rest call="account" httpMethod="POST"/>
    </documentation>
</operation>
У нас на PHP проекте API описано на WSDL, это описание работает и для первичной валидации. Документацию получаем с помощью XSLT преобразования WSDL-ки. Подход хорошо себя зарекомендовал. Но приведенный в статье набор инструментов вокруг RAML впечатляет.

Information

Rating
4,545-th
Location
Бишкек, Кыргызстан, Кыргызстан
Date of birth
Registered
Activity