Django_-_podrobnoe_rukovodstvo
.pdf400 |
Глава 20. Безопасность |
Но те же сообщения на действующем сайте могут выдать злоумышленнику такую информацию о вашем коде или конфигурации системы, которая позволит ему осуществить атаку.
К тому же информация об ошибках совершенно неинтересна обычным пользователям. В Django считается, что посетители сайта не должны видеть сообщений, касающихся ошибок в работе приложения. В случае появления необработанного исключения посетитель не должен видеть полную трассировку, да и вообще какие-то фрагменты кода или сообщения интерпретатора Python (ориентированные на программистов). Посетитель должен видеть только сообщение «Эта страница недоступна».
Естественно, программист должен видеть сообщения об ошибках, чтобы исправить их. Поэтому система должна скрывать эту информацию от обычных пользователей, но показывать ее доверенным разработчикам сайта.
Решение
В главе 12 уже отмечалось, что отображением сообщений об ошибках
вDjango управляет параметр DEBUG. Перед началом развертывания убедитесь, что он усановлен в значение False.
При развертывании на платформе Apache + mod_python (глава 12) следует также включить в конфигурационный файл Apache директиву PythonDebug Off; она подавляет сообщения об ошибках, возникающих еще до передачи управления Django.
Заключительное слово о безопасности
Мы надеемся, что не слишком запугали вас этим разговором о безопасности. Да, Интернет таит в себе угрозы, но, будучи предусмотрительным, вы сможете создать безопасный сайт.
Не забывайте, что представления о безопасности в Интернете постоянно изменяются; если вы читаете устаревшее издание этой книги, то обязательно справьтесь в более актуальных источниках – не появились ли какие-нибудь новые уязвимости? Вообще, имеет смысл раз в неделю или в месяц потратить некоторое время на ознакомление с текущим состоянием дел в сфере безопасности веб-приложений. Не такие уж высокая плата за безопасность своего сайта и пользователей.
Что дальше?
Вот вы и дошли до конца основного курса. В приложениях вы найдете справочный материал, полезный в ходе работы над проектами Django.
Желаем вам удачи в эксплуатации Django-сайта, будь то развлечение для себя и своих друзей или следующее воплощение Google.
IV
Приложения
A
Справочник по моделям
Основные сведения об определении моделей были приведены в главе 5 и использовались на протяжении всей книги. Однако многочисленные параметры так и остались не рассмотренными. В этом приложении мы расскажем обо всех параметрах моделей.
Отметим, что, хотя описываемый ниже API считается устоявшимся, тем не менее разработчики Django все время добавляют новые вспомогательные функции и средства. Поэтому рекомендуем почаще заглядывать в актуальную документацию на сайте http://docs.djangoproject. com/.
Поля
Самая важная часть модели – и единственная обязательная – список полей базы данных.
Каждое поле модели должно быть объектом класса, являющегося подклассом Field. В Django класс поля определяет следующие его характеристики:
•• Тип столбца в базе данных (INTEGER, VARCHAR и т. д.).
•• Элемент, с помощью которого поле отображается в формах и административном интерфейсе Django, если вы собираетесь им пользоваться (<input type=”text”>, <select> и т. д.).
•• Минимальные требования к проверке данных, применяемые в административном интерфейсе и в формах.
Ниже приведен полный перечень классов полей в алфавитном порядке. Поля, описывающие отношения между таблицами (ForeignKey и др.), рассматриваются в следующем разделе.
404 |
Приложение A. Справочник по моделям |
Ограничения на имена полей
В Django накладывается всего два ограничения на имена полей модели:
•• Имя поля не должно совпадать с зарезервированным словом языка Python, потому что это привело бы к синтаксической ошибке. Например:
class Example(models.Model):
pass = models.IntegerField() # ‘pass’ – зарезервированное слово!
•• Имя поля не должно содержать подряд несколько знаков подчеркивания из-за особенностей работы механизма запросов в Django. Например:
class Example(models.Model):
foo__bar = models.IntegerField() # ‘foo__bar’ содержит два символа
# подчеркивания подряд!
Впрочем, эти ограничения можно обойти, поскольку имя поля модели не обязано совпадать с именем столбца базы данных (см. раздел «Параметр db_column» ниже).
Зарезервированные слова языка SQL, например join, where, select, допускается использовать в качестве имен полей модели, потому что Django экранирует имена таблиц и столбцов в SQL-запросах, применяя соглашения об употреблении кавычек, действующие в указанной СУБД.
Класс AutoField
Подкласс класса IntegerField, описывающий автоинкрементное поле. Обычно явно создавать поля такого типа не требуется; по умолчанию Django автоматически добавляет в модель поле первичного ключа.
Класс BooleanField
Поле, принимающее значения true/false.
Для пользователей MySQL…
В MySQL булевские поля хранятся в столбцах типа TINYINT и принимают значение 0 или 1 (в большинстве СУБД имеется настоящий тип BOOLEAN или его эквивалент). Поэтому для MySQL – и только в этом случае – выбранное из базы и сохраненное в атрибуте модели поле типа BooleanField будет принимать значения 0 или 1, а не True или False.
Поля |
405 |
Обычно это неважно, потому что Python гарантирует, что оба выражения 1 == True и 0 == False истинны. Просто будьте внимательны при выполнении таких проверок, как obj is True, когда obj – значение булевского атрибута модели. Если модель реализована в СУБД MySQL, то эта проверка завершится неудачей. В подобных случаях лучше сравнивать значения на равенство (оператором ==).
Класс CharField
Строковое поле для хранения строк небольшого и умеренного размера. (Для очень больших текстов пользуйтесь классом TextField.)
Конструктор класса CharField принимает еще один обязательный аргумент: max_length. Он определяет максимальную длину поля (в символах). Наличие этого атрибута проверяется как на уровне Django, так и на уровне самой СУБД.
Класс CommaSeparatedIntegerField
Набор целых чисел, разделенных запятыми. Как и в случае CharField, аргумент max_length обязателен.
Класс DateField
Дата, представленная в Python объектом класса datetime.date.
Класс DateTimeField
Дата и время, представленные в Python объектом класса datetime.datetime.
Класс DecimalField
Десятичное число с фиксированной точностью, представленное в Python объектом класса Decimal. Имеет два обязательных аргумента:
•• max_digits – максимальное количество цифр в числе.
•• decimal_place – количество десятичных знаков после запятой.
Например, если требуется хранить числа до 999 с точностью 2 знака после запятой, то следует использовать такое определение:
models.DecimalField(..., max_digits=5, decimal_places=2)
А поле для хранения чисел до миллиарда с точностью 10 знаков после запятой определяется так:
models.DecimalField(..., max_digits=19, decimal_places=10)
406 |
Приложение A. Справочник по моделям |
Полю типа DecimalField можно присвоить либо объект типа decimal. Decimal, либо строку, но не число с плавающей точкой в смысле Python.
Класс EmailField
Подкласс класса CharField, проверяющий, является ли значение допустимым адресом электронной почты.
Класс FileField
Поле для выгрузки файлов на сервер.
Примечание
В конструкторах полей этого типа аргументы primary_key и unique не поддерживаются; при попытке определить любой из них будет возбуждено исключение TypeError.
Имеет один обязательный аргумент:
upload_to
Путь в локальной файловой системе, который будет дописан в конец параметра MEDIA_ROOT при вычислении значения атрибута django.core.files. File.url.
Этот путь может содержать спецификаторы формата, принятые в функции strftime (см. описание стандартного модуля time в документации по языку Python). Они будут заменены датой и временем загрузки файла (чтобы все загружаемые файлы не оказывались в одном каталоге).
Кроме того, путь может быть представлен вызываемым объектом, например функцией; она будет вызвана для формирования полного пути загружаемого файла вместе с именем. Вызываемый объект должен принимать два аргумента и возвращать UNIX-путь (компоненты отделяются символом слеша), который будет передан файловой системе. Аргументы описаны в табл. A.1.
Таблица A.1. Аргументы, передаваемые вызываемому объекту upload_to
Аргумент Описание
instance Экземпляр модели, где определено поле типа FileField. Точнее, это тот экземпляр, к которому присоединяется загруженный файл.
В большинстве случаев этот объект еще не сохранен
вбазе данных, поэтому если в нем имеется добавленное по умолчанию поле первичного ключа типа AutoField,
то значение ему еще не присвоено.
filename Исходное имя файла. Его можно учитывать или не учитывать при определении окончательного пути к файлу.
Поля |
407 |
Имеется также необязательный аргумент:
storage
Необязательный: объект, отвечающий за сохранение и извлечение файлов.
Чтобы в модели можно было использовать поля типа FileField или ImageField (см. раздел «Класс ImageField»), необходимо соблюсти следующие условия.
1.В файле параметров должен быть определен параметр MEDIA_ROOT – полный путь к каталогу, куда Django будет сохранять выгруженные файлы (для повышения производительности файлы не хранятся в базе данных). Кроме того, задайте параметр MEDIA_URL – базовый URL, соответствующий этому каталогу. Убедитесь, что веб-сервер обладает разрешением на запись в указанный каталог.
2.Включите в модель поле типа FileField или ImageField и не забудьте определить параметр upload_to, который сообщит Django, в какой подкаталог MEDIA_ROOT загружать файлы.
3.В базе данных будет храниться только путь к файлу (относительно MEDIA_ROOT). Django предлагает удобную функцию url(). Так, если поле типа ImageField называется mug_shot, то получить в шаблоне абсолютный URL изображения можно с помощью {{ object.mug_shot.url }}.
Пусть, например, параметр MEDIA_ROOT имеет значение ‘/home/media’, а аргумент upload_to содержит строку ‘photos/%Y/%m/%d’. Часть ‘%Y/%m/%d’ этой строки содержит спецификаторы формата в стиле функции strftime: ‘%Y’ – четырехзначный номер года, ‘%m’ – двузначный номер месяца, а ‘%d’ – двузначный номер дня. Файл, выгруженный на сервер 15 января 2007, будет сохранен в каталоге /home/media/photos/2007/01/15.
Чтобы узнать имя выгруженного файла на диске, URL, ссылающийся на этот файл, или размер файла, воспользуйтесь соответственно атрибутами name, url и size.
Отметим, что при выгрузке файлов нужно следить за тем, откуда они выгружаются, и обращать внимание на типы файлов во избежание появления брешей в системе безопасности. Обязательно анализируйте все выгруженные файлы, проверяя их принадлежность к типу, который был заявлен. Например, если слепо копировать выгруженные неизвестно кем файлы в подкаталог корня документов веб-сервера, то там может оказаться CGIили PHP-сценарий, который будет выполнен при обращении к URL, соответствующему файлу. Не допускайте этого.
По умолчанию объект типа FileField представлен в базе столбцом типа varchar(100). Как и для других полей, максимальную длину столбца можно изменить с помощью аргумента max_length.
408 |
Приложение A. Справочник по моделям |
Класс FilePathField
Подкласс класса CharField, значения которого ограничены именами файлов в некотором каталоге файловой системы. Конструктор принимает три специальных аргумента, первый из которых является обязательным:
path
Обязательный. Абсолютный путь к каталогу, относительно которого откладываются пути, хранящиеся в поле. Например, “/home/images”.
match
Необязательный. Регулярное выражение в виде строки, которому должны удовлетворять имена файлов в поле типа FilePathField. Это регулярное выражение применяется к базовому имени файла, а не к полному пути. Например, выражению “foo.*\.txt$” файл с именем foo23.txt будет соответствовать, а файлы bar.txt или foo23.gif – нет.
recursive
Необязательный. True или False, по умолчанию False. Указывает, нужно ли включать также все подкаталоги path.
Разумеется, все эти аргументы можно указывать одновременно.
Еще раз обратим внимание, что регулярное выражение match сопоставляется с базовым именем файла, а не с полным путем. Поэтому приведенному далее выражению соответствует файл /home/images/bar/foo. gif, но не файл /home/images/foo/bar.gif, так как выражение в параметре match применяется к именам foo.gif и bar.gif, а не к полным путям:
FilePathField(path=”/home/images”, match=”foo.*”, recursive=True)
По умолчанию объект типа FilePathField представлен в базе столбцом типа varchar(100). Как и для других полей, максимальную длину столбца можно изменить с помощью аргумента max_length.
Класс FloatField
Число с плавающей точкой, представленное типом Python float.
Класс ImageField
Аналогичен FileField, но проверяет, действительно ли выгруженный файл содержит изображение. Конструктор принимает два дополнительных необязательных аргумента:
height_field
Имя поля модели, в которое при сохранении автоматически будет записана высота изображения.
width_field
Имя поля модели, в которое при сохранении автоматически будет записана ширина изображения.
Поля |
409 |
Помимо специальных атрибутов, имеющихся в классе FileField, класс ImageField содержит еще атрибуты height и width – соответственно высоту и ширину изображения в пикселах.
Для таких полей необходима библиотека Python Imaging Library, которую можно скачать со страницы http://www.pythonware.com/products/ pil/.
По умолчанию объект типа ImageField представлен в базе столбцом типа varchar(100). Как и для других полей, максимальную длину столбца можно изменить с помощью аргумента max_length.
Класс IntegerField
Целое число.
Класс IPAddressField
IP-адрес в строковом формате (например, ‘192.0.2.30’).
Класс NullBooleanField
Аналогичен классу BooleanField, но может также содержать значение NULL. Используйте вместо BooleanField с атрибутом null=True.
Класс PositiveIntegerField
Положительное целое число
Класс PositiveSmallIntegerField
Аналогичен классу PositiveIntegerField, но допускает значения, не превышающие некоторого порога (зависящего от конкретной СУБД).
Класс SlugField
Литая строка (slug) – термин, применяемый в полиграфии для обозначения строки, содержащей только буквы, цифры, символы подчеркивания и дефисы. Обычно этот тип используются для представления URL.
Как и для класса CharField, можно определить аргумент max_length. Если значение max_length не задано, по умолчанию Django будет использовать длину 50.
Для полей этого типа атрибут db_index автоматически получает значение True.
Класс SmallIntegerField
Аналогичен классу IntegerField, но может принимать значения только в определенном диапазоне (зависит от конкретной СУБД).
