На каком этапе лучше проверять токен в Django
Что проверяют
Знаете ли вы порядок обработки запроса в Django и DRF и различаете ли аутентификацию и авторизацию. Ответ «в middleware» звучит логично и почти всегда неверен, ради этого вопрос и задают.
Как отвечать
Если проект на DRF, проверка токена живёт в классе аутентификации, а не в middleware:
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework_simplejwt.authentication.JWTAuthentication",
),
}Порядок такой: middleware проходит по всем запросам, дальше на входе во view DRF вызывает аутентификацию (лениво, при первом обращении к request.user), затем проверяет права из permission_classes и ограничения частоты. Аутентификация отвечает на вопрос «кто это» и даёт 401 на плохой токен, права отвечают «пустить ли его сюда» и дают 403. Открытый эндпоинт помечается разрешением AllowAny, обходить ничего не нужно.
Middleware остаётся для сквозного: идентификатор запроса, логирование, заголовки безопасности. Глобальная проверка токена там ломает всё, что не является вашим API: админку, статику, проверку живости, схему документации, а заодно и сам вход с обновлением токена.
Если DRF в проекте нет, роль класса аутентификации играет декоратор или миксин на конкретной view, а не общий фильтр на весь проект.
Где спотыкаются
Пишут middleware, который режет все адреса, и потом обвешивают его списком исключений по префиксам пути. Этот список и становится местом, где со временем появляется дыра: добавили служебный маршрут, забыли про проверку.
Второе: берут заголовок Authorization целиком и отдают в декодер вместе со схемой Bearer, не разобрав строку, а секрет держат прямо в коде. Секрет читают из настроек, схему отделяют явно, а список допустимых алгоритмов задают жёстко.
Третье: отключают проверку подписи, чтобы «просто достать payload», или не проверяют тип токена и срок действия. Сюда же уверенность, что выход из системы делает токен недействительным: подписанный токен работает до истечения срока, для отзыва нужен чёрный список или короткий срок жизни с обновлением.