Middleware – особый объект, который обычно изменяет входящий запрос или исходящий ответ. Например, добавляет заголовки, делает предварительные проверки. Middleware нужен, когда требуется подвергнуть обработке все запросы приложения.
На уровне языка это объект с методами process_request
и process_response
. Методы должны вернуть принятый объект (запрос или ответ) для дальнейшей обработки или выкинуть исключение, если что-то не в порядке. В этом случает дальнейшая обработка прекращается.
Чтобы включить Middleware, достаточно добавить путь к нему в список MIDDLEWARE
.
SessionMiddleware
– поддержка сессий. Добавляет в запрос объект session
CsrfViewMiddleware
– проверяет, что POST-запросы отправлены с текущего доменаAuthenticationMiddleware
– авторизует пользователя. Добавляет в запрос поле user
MessageMiddleware
– передает пользователю короткие сообщенияНа каждый запрос система генерирует уникальный токен и выставляет его в куках. В каждой форме размещается скрытое поле csrf-token
с этим же токеном. При отправке формы методом POST
Джанго проверяет, что поле формы и значение в куках совпадают. Если нет, это значит, что запрос подделан или отправлен с другого домена.
Чтобы освободить какую-то вьюху от проверки (если это API, например), достаточно обернуть ее декоратором csrf_except
.
Промежуточный слой CSRF и шаблонный тег предоставляют легкую-в-использовании защиту против Межсайтовой подделки запроса. Этот тип атак случается, когда злонамеренный Web сайт содержит ссылку, кнопку формы или некоторый javascript, который предназначен для выполнения некоторых действий на вашем Web сайте, используя учетные данные авторизованного пользователя, который посещал злонамеренный сайт в своем браузере. Сюда также входит связанный тип атак, ‘login CSRF’, где атакуемый сайт обманывает браузер пользователя, авторизируясь на сайте с чужими учетными данными.
Первая защита против CSRF атак - это гарантирование того, что GET запросы (и другие ‘безопасные’ методы, определенные в 9.1.1 Safe Methods, HTTP 1.1, RFC 2616#section-9.1.1) свободны от побочных эффектов. Запросы через ‘небезопасные’ методы, такие как POST, PUT и DELETE могут быть защищены при помощи шагов, описанных ниже.
Как это работает:
CSRF базируется на следующих вещах:
CSRF кука, которая устанавливается как случайное число (сессия независимого случайного слова, как это еще иногда называют), к которой другие сайты не будут иметь доступа. Эта кука устанавливается при помощи CsrfViewMiddleware. Она должно быть постоянной, но так как нет способа установить куки, у которых никогда не истекает время жизни, то она отправляется с каждым ответом, который вызывал django.middleware.csrf.get_token() (функция использовалась внутри для получения CSRF токена).
Все POST формы содержат скрытое поле ‘csrfmiddlewaretoken’. Значение поля равно CSRF куке. Эта часть выполняет шаблонным тегом.
Все HTTP запросы, которые не GET, HEAD, OPTIONS или TRACE, должны содержать CSRF куку, и поле ‘csrfmiddlewaretoken’ с правильным значением. Иначе пользователь получит 403 ошибку. Эта проверка выполняется в CsrfViewMiddleware.
В дополнение для HTTPS запросов в CsrfViewMiddleware проверяется “referer”(источник запроса). Это необходимо для предотвращения MITM-атаки(Man-In-The-Middle), которая возможна при использовании HTTPS и токена не привязанного к сессии, т.к. клиенты принимают(к сожалению) HTTP заголовок ‘Set-Cookie’, несмотря на то, что коммуникация с сервером происходит через HTTPS. (Такая проверка не выполняется для HTTP запросов т.к. “Referer” заголовок легко подменить при использовании HTTP.) Если указана настройка CSRF_COOKIE_DOMAIN, значение “referer” будет сравниваться с этим значением. Значение поддерживает под-домены. Например, CSRF_COOKIE_DOMAIN = ‘.example.com’ позволить отправлять POST запросы с www.example.com и api.example.com. Если настройка не указана, “referer” должен быть равен HTTP заголовку Host. Чтобы расширить список доступных доменов, кроме текущего хоста и домена кук, используйте CSRF_TRUSTED_ORIGINS.
Такой подход гарантирует, что только формы, отправленные с доверенных доменов, могут передавать POST данные.
GET игнорируются сознательно (и все другие запросы, которые считаются “безопасными” в соответствии с RFC 2616). Эти запросы никогда не должны выполнять каких-либо потенциально опасные действия, и CSRF атаки через GET запрос должен быть безвредным. RFC 2616 определяет POST, PUT и DELETE как “небезопасные”.
Сигналы – это события в экосистеме Джанго. С помощью сигналов подсистемы оповещают приложение о том, что случилось. Чтобы читать сигналы, программист регистрирет обработчики сигналов. Сигналы распространяются синхронно. Это значит, подписав на один сигнал сотню обработчиков, мы увеличим время, необходимое на отдачу ответа.
Основные сигналы это начало запроса и его окончание, перед сохранением модели и после, обращение к базе данных.
Важно: сигналы моделей работают поштучно, то есть для одной модели. При пакетной обработке, например, queryset.all().delete()
или queryset.all().update({'foo'=42})
, события об удалении или изменения не будут вызваны.
Если есть модели A и B со связью многие ко многим, то создается таблица-мост с именем a_to_b
, которая хранит ключ на A, ключ на B и дополнительные сведения, например, время, когда была создана связь. Эта таблица сцепляется с A и B оператором JOIN
.
Форму можно отправлять обоими способами. В первом случае переменные прикрепляются к строке запроса после вопросительного знака. Во втором – передаются в теле запроса.
Техническое ограничение метода GET в том, что им нельзя передать файл, в отличие от POST.
Форму желательно передавать методом POST по следующим причинам:
Serializer преобразует информацию, хранящуюся в базе данных и определенную с помощью моделей Django, в формат, который легко и эффективно передается через API.
Модели Django интуитивно представляют данные, хранящиеся в базе, но API должен передавать информацию в менее сложной структуре. Хотя данные будут представлены как экземпляры классов Model, их необходимо перевести в формат JSON для передачи через API.
Сериализатор DRF производит это преобразование. Когда пользователь передает информацию (например, создание нового экземпляра) через API, сериализатор берет данные, проверяет их и преобразует в нечто, что Django может сложить в экземпляр модели. Аналогичным образом, когда пользователь обращается к информации через API, соответствующие экземпляры передаются в сериализатор, который преобразовывает их в формат, который может быть легко передан пользователю как JSON.
Наиболее распространенной формой, которую принимает сериализатор DRF, является тот, который привязан непосредственно к модели Django:
class ThingSerializer(serializers.ModelSerializer):
class Meta:
= Thing
model = (‘name’, ) fields
Настройки fields позволяют точно указать, какие поля доступны этому сериализатору. В качестве альтернативы, может быть установлен exclude вместо fields, которое будет включать все поля модели, кроме тех, которые указаны в exclude.
Сериализаторы — это невероятно гибкий и мощный компонент DRF. Хотя подключение сериализатора к модели является наиболее распространенным, сериализаторы могут использоваться для создания любой структуры данных Python через API в соответствии с определенными параметрами.
Django во многом работает через метаклассы.
Если коротко, то метаклассы - это классы, которые конструируют другие классы. Объявляются они через атрибут класса __metaclass__
(в джанге через слой совместимости с python 3 через модуль six до версии 2).
Поэтому когда Django конструирует ваш класс, она делает это с помощью своего метакласса. Чтобы при конструировании ей знать какие-то параметры вашего класса, ну, например модель или поля в вашем случае, она ищет в вашем классе класс с названием Meta.
Вообще вся эта магия с метаклассами очень важна в джанге и поэтому лучше саму логику становления класса не переопределять.
Если взять за пример Serializer, то можно посмотреть на код джанги:
@six.add_metaclass(SerializerMetaclass)
class Serializer(BaseSerializer):
...
SerializerMetaclass - это тот самый метакласс, который конструирует класс ModelForm.
В классе Meta сериализатора можно задать модель по которой будет создан сериализатор, поля, которые будут включены (или exclude для исключения), list_serializer_class
, например для того чтобы задать специфическую валидацию списков и тд.
Насчет быстродействия затрудняюсь ответить, потому что это довольно каверзный вопрос, тестов лично я не проводил. Но, что касается отличий этих двух фреймворков:
Под каждую задачу нужно брать свой инструмент, Django хорошо подойдет для новостных сайтов, блогов и тд, благодаря тому что у него уже из коробки есть многое (в том числе админка), да и создавался он именно под такой тип сайтов. Flask же из коробки напротив, практически ничего не имеет и лучше подойдет для каких-либо микросервисов или приложений для которых стек технологий с которыми поставляется Django не подходит.
Django поставляется с системой аутентификации пользователей. Она обеспечивает пользовательские аккаунты, группы, права и сессии на основе куки.
Система аутентификации Django отвечает за оба аспекта: аутентификацию и авторизацию. Если коротко, то аутентификация проверяет пользователя, а авторизация определяет, что аутентифицированный пользователь может делать. Далее термин “аутентификация” будет использоваться для обозначения обоих аспектов (User authentication in Django).
Система аутентификации состоит из:
Аутентификационная система Django старается быть очень простой и не предоставляет некоторые фичи, распространённые в других системах веб аутентификации. Такие фичи реализованы в сторонних пакетах: