Предоставление имен таблиц и полей в URL-адресе запроса

мне было поручено создать этот компонент Joomla (да, joomla; но он не связан), и профессор сказал мне, что я должен сделать свой код как можно более динамичным (код, который требует меньшего обслуживания) и избежать жесткого кодирования. Подход, который мы изначально думали, - это взять параметры url, превратить их в объекты и передать их в запрос.

допустим, мы хотим прочитать отель с id # 1 в таблице "отели". допустим в таблице есть поля "hotel_id", "hotel_name" и некоторые другие поля.

теперь подход, который мы приняли при создании строки запроса sql, заключается в анализе запроса url, который выглядел так:

index.php?task=view&table=hotels&hotel_id=1&param1=something&param2=somethingelse

и превратил его в объект PHP, как это (показано в эквиваленте JSON, легче понять):

obj = {
  'table':'hotel',
  'conditions':{
        'hotel_id':'1',
        'param1':'something',
        'param2':'somethingelse'
}

и SQL-запрос будет чем-то вроде этого, где условия зацикливаются и добавляются в строку, где поле и значение предложения WHERE являются ключом и значением объекта (все еще в форме JSON для легкость):

SELECT * FROM obj.table WHERE hotel_id=1 AND param1=something and so on...

проблема, которая меня беспокоила, заключалась в том, что имя таблицы и имена полей в url-адресе запроса. Я знаю, что это создает угрозу безопасности, подвергая элементы, которые должны быть видны только на стороне сервера. Текущее решение, о котором я думаю, дает псевдонимы каждой таблице и полю для клиентской стороны, но это будет жесткое кодирование, что противоречит его политике. и кроме того, если бы я сделал это и имел тысячу таблиц для псевдонима, это не было бы практическое.

каков правильный метод для этого без:

  1. жесткого кодирования вещи
  2. держите код как динамический и адаптируемый

EDIT:

что касается произвольных запросов (я забыл включить это), то в настоящее время их останавливает функция, которая берет ссылку из жестко закодированного объекта (больше похоже на файл конфигурации, показанный здесь), и анализирует url, выбирая параметры или под стать им.

конфигурация выглядит так:

// 'hotels' here is the table name. instead of parsing the url for a table name
// php will just find the table from this config. if no match, return error.
// reduces risk of arbitrary tables.

'hotels' => array(      

  // fields and their types, used to identify what filter to use

  'structure' => array(  
    'hotel_id'=>'int',
    'name'=>'string',
    'description'=>'string',
    'featured'=>'boolean',
    'published'=>'boolean'
  ),

   //these are the list of 'tasks' and accepted parameters, based on the ones above
   //these are the actual parameter names which i said were the same as field names
   //the ones in 'values' are usually values for inserting and updating
   //the ones in 'conditions' are the ones used in the WHERE part of the query

  'operations' =>array(  
    'add' => array(
      'values' => array('name','description','featured'),
      'conditions' => array()
    ),
    'view' => array(
    'values' => array(),
    'conditions' => array('hotel_id')
    ),
    'edit' => array(
    'values' => array('name','description','featured'),
    'conditions' => array('hotel_id')
    ),
    'remove' => array(
    'values' => array(),
    'conditions' => array('hotel_id')
    )
  )
)

и так, из этого списка конфиг:

  • если параметры, отправленные для задачи, не завершены, сервер возвращает ошибку.
  • если параметр из url удваивается, берется только первый прочитанный параметр.
  • любые другие параметры не в конфигурации отбрасываются
  • если эта задача не разрешена, она не будет указана для этой таблицы
  • если задача не там, сервер возвращает ошибку
  • если таблицы нет, сервер возвращает ошибку

Я фактически сделал это после просмотра компонента в joomla, который использует эту стратегию. Это уменьшает модель и контроллер до 4 динамических функций, которые были бы CRUD, оставляя только файл конфигурации, чтобы быть единственным файлом, редактируемым позже (это было то, что я имел в виду о динамическом коде, я только добавляю таблицы и задачи, если нужны дополнительные таблицы), но я боюсь, что это может наложить безопасность риск, которого я, возможно, еще не знал.

есть идеи для альтернативы?

3 ответов


у меня нет проблем с использованием одних и тех же (или очень похожих) имен в URL и базе данных - конечно, вы можете "разоблачать" детали реализации, но если вы выбираете радикально разные имена в URL и БД, вы, вероятно, выбираете плохие имена. Я также поклонник последовательного именования-общение с кодерами/тестерами / клиентами становится намного сложнее, если все называют все немного иначе.

что меня беспокоит, так это то, что вы позволяете пользователю работать произвольные запросы к базе данных. http://.../index.php?table=users&user_id=1, сказать? Или http://.../index.php?table=users&password=password (Не то, что вы должны хранить пароли в открытом виде)? Или http://.../index.php?table=users&age=11?

если пользователь, подключенный к БД, имеет те же разрешения, что и пользователь, сидящий перед веб-браузером, это может иметь смысл. Как правило, это не так, поэтому вам понадобится какой-то слой, который знает, что такое пользователь, и не может видеть, и этот слой намного проще правильно написать белым списком.

(Если вы вставил достаточно логики в хранимые процедуры, тогда это может сработать, но тогда ваши хранимые процедуры будут имена столбцов жесткого кода...)


при составлении SQL-запроса с данными из входных данных он представляет угрозу безопасности. Но имейте в виду, что значения столбцов вставляются в поля, принимая входные данные от пользователя, анализируя его и составляя с ним SQL-запрос (за исключением подготовленных операторов). Поэтому, когда все сделано правильно, вам не о чем беспокоиться - просто ограничьте пользователя этими столбцами и таблицами. Код/база данных программного обеспечения с открытым исходным кодом видны всем - и это не вредит системе так сильно, как было бы думать.


ваш aliasses может быть rot13() на мета / имя ваших объектов.

хотя, если вы избегаете ввода соответственно при работе с этими именами, я не вижу никаких проблем в раскрытии их имен.