Аутентификация
Аутентификация
Аутентификация должна быть подключаемой.
Джейкоб Каплан-Мосс, "Худшие практики REST"
Аутентификация - это механизм связывания входящего запроса с набором идентификационных данных, таких как пользователь, от которого пришел запрос, или токен, которым он был подписан. Политики permission и throttling могут затем использовать эти учетные данные, чтобы определить, должен ли запрос быть разрешен.
DRF предоставляет несколько схем аутентификации из коробки, а также позволяет реализовать пользовательские схемы.
Аутентификация всегда выполняется в самом начале представления, до того, как произойдет проверка разрешений и дросселирование, и до того, как будет разрешено выполнение любого другого кода.
Свойство request.user
обычно устанавливается на экземпляр класса User
пакета contrib.auth
.
Свойство request.auth
используется для любой дополнительной информации об аутентификации, например, оно может быть использовано для представления маркера аутентификации, которым был подписан запрос.
Примечание: Не забывайте, что аутентификация сама по себе не разрешает и не запрещает входящий запрос, она просто идентифицирует учетные данные, с которыми был сделан запрос.
Информацию о том, как настроить политику разрешений для вашего API, смотрите в документации permissions.
Как определяется аутентификация
Схемы аутентификации всегда определяются как список классов. DRF попытается выполнить аутентификацию с каждым классом в списке, и установит request.user
и request.auth
, используя возвращаемое значение первого класса, который успешно аутентифицируется.
Если ни один класс не выполнит аутентификацию, request.user
будет установлен в экземпляр django.contrib.auth.models.AnonymousUser
, а request.auth
будет установлен в None
.
Значение request.user
и request.auth
для неаутентифицированных запросов можно изменить с помощью параметров UNAUTHENTICATED_USER
и UNAUTHENTICATED_TOKEN
.
Установка схемы аутентификации
Схемы аутентификации по умолчанию можно установить глобально, используя параметр DEFAULT_AUTHENTICATION_CLASSES
. Например.
Вы также можете установить схему аутентификации для каждого представления или каждого набора представлений, используя класс APIView
, основанный на представлениях.
Или, если вы используете декоратор @api_view
с представлениями, основанными на функциях.
Неавторизованные и запрещенные ответы
Когда неаутентифицированному запросу отказано в разрешении, существует два различных кода ошибок, которые могут быть уместны.
Ответы HTTP 401 всегда должны содержать заголовок WWW-Authenticate
, который указывает клиенту, как пройти аутентификацию. Ответы HTTP 403 не включают заголовок WWW-Authenticate
.
Тип ответа, который будет использоваться, зависит от схемы аутентификации. Хотя может использоваться несколько схем аутентификации, для определения типа ответа может использоваться только одна схема. Первый класс аутентификации, установленный в представлении, используется при определении типа ответа.
Обратите внимание, что когда запрос может успешно пройти аутентификацию, но при этом получить отказ в разрешении на выполнение запроса, в этом случае всегда будет использоваться ответ 403 Permission Denied
, независимо от схемы аутентификации.
Специфическая конфигурация Apache mod_wsgi
Обратите внимание, что при развертывании на Apache using mod_wsgi заголовок авторизации по умолчанию не передается приложению WSGI, так как предполагается, что аутентификация будет обрабатываться Apache, а не на уровне приложения.
Если вы развертываете на Apache и используете любую аутентификацию, не основанную на сеансах, вам необходимо явно настроить mod_wsgi для передачи необходимых заголовков приложению. Это можно сделать, указав директиву WSGIPassAuthorization
в соответствующем контексте и установив ее в значение 'On'
.
API Reference
BasicAuthentication
Эта схема аутентификации использует HTTP Basic Authentication, подписанную именем пользователя и паролем. Базовая аутентификация обычно подходит только для тестирования.
При успешной аутентификации BasicAuthentication
предоставляет следующие учетные данные.
request.user
будет экземпляром DjangoUser
.request.auth
будетNone
.
Ответы без аутентификации, которым отказано в разрешении, приведут к ответу HTTP 401 Unauthorized
с соответствующим заголовком WWW-Authenticate. Например:
Примечание: Если вы используете BasicAuthentication
в реальном проекте, вы должны убедиться, что ваш API доступен только через https
. Вы также должны убедиться, что клиенты вашего API всегда будут повторно запрашивать имя пользователя и пароль при входе в систему и никогда не будут сохранять эти данные в постоянном хранилище.
TokenAuthentication
Примечание: Аутентификация с помощью токенов, предоставляемая DRF, является довольно простой реализацией.
Для реализации, которая позволяет использовать более одного токена на пользователя, имеет некоторые более жесткие детали реализации безопасности и поддерживает истечение срока действия токена, пожалуйста, обратитесь к стороннему пакету Django REST Knox.
Эта схема аутентификации использует простую схему аутентификации HTTP на основе токенов. Токен-аутентификация подходит для клиент-серверных установок, таких как собственные настольные и мобильные клиенты.
Для использования схемы TokenAuthentication
вам необходимо настроить классы аутентификации, чтобы включить TokenAuthentication
, и дополнительно включить rest_framework.authtoken
в настройку INSTALLED_APPS
:
Обязательно запустите manage.py migrate
после изменения настроек.
Приложение rest_framework.authtoken
обеспечивает миграцию баз данных Django.
Вам также потребуется создать токены для своих пользователей.
Для аутентификации клиентов ключ токена должен быть включен в HTTP-заголовок Authorization
. Ключ должен иметь префикс в виде строкового литерала "Token", с пробелами, разделяющими эти две строки. Например:
*Если вы хотите использовать другое ключевое слово в заголовке, например Bearer
, просто создайте подкласс TokenAuthentication
и установите переменную класса keyword
.
При успешной аутентификации TokenAuthentication
предоставляет следующие учетные данные.
request.user
будет экземпляром DjangoUser
.request.auth
будет экземпляромrest_framework.authtoken.models.Token
.
Ответы без аутентификации, которым отказано в разрешении, приведут к ответу HTTP 401 Unauthorized
с соответствующим заголовком WWW-Authenticate. Например:
Инструмент командной строки curl
может быть полезен для тестирования API с аутентификацией токенов. Например:
Примечание: Если вы используете TokenAuthentication
в реальном проекте, вы должны убедиться, что ваш API доступен только через https
.
Генерация токенов
С помощью сигналов
Если вы хотите, чтобы у каждого пользователя был автоматически сгенерированный токен, вы можете просто перехватить сигнал post_save
пользователя.
Обратите внимание, что вам нужно убедиться, что вы поместили этот фрагмент кода в установленный модуль models.py
или в другое место, которое будет импортироваться Django при запуске.
Если вы уже создали несколько пользователей, вы можете сгенерировать токены для всех существующих пользователей следующим образом:
Посредством конечной точки API
При использовании TokenAuthentication
вы можете захотеть предоставить клиентам механизм для получения токена, заданного именем пользователя и паролем. DRF предоставляет встроенное представление для обеспечения такого поведения. Чтобы использовать его, добавьте представление obtain_auth_token
в URLconf:
Обратите внимание, что URL часть шаблона может быть любой, которую вы хотите использовать.
Представление obtain_auth_token
вернет ответ в формате JSON, если действительные поля username
и password
будут отправлены в представление с помощью данных формы или JSON:
Обратите внимание, что представление по умолчанию obtain_auth_token
явно использует JSON запросы и ответы, а не использует классы рендерера и парсера по умолчанию в ваших настройках.
По умолчанию к представлению obtain_auth_token
не применяется никаких разрешений или дросселирования. Если вы хотите применить дросселирование, вам нужно переопределить класс представления и включить их с помощью атрибута throttle_classes
.
Если вам нужна настраиваемая версия представления obtain_auth_token
, вы можете сделать это, создав подкласс класса представления ObtainAuthToken
и используя его в url conf.
Например, вы можете возвращать дополнительную информацию о пользователе помимо значения token
:
И в вашем urls.py
:
С администратором Django
Токены также можно создавать вручную через интерфейс администратора. В случае, если вы используете большую базу пользователей, мы рекомендуем вам пропатчить класс TokenAdmin
, чтобы настроить его под свои нужды, в частности, объявив поле user
как raw_field
.
ваше_приложение/admin.py
:
Использование команды Django manage.py
Начиная с версии 3.6.4 можно сгенерировать пользовательский токен с помощью следующей команды:
эта команда вернет API-токен для данного пользователя, создав его, если он не существует:
Если вы хотите восстановить токен (например, если он был скомпрометирован или произошла утечка), вы можете передать дополнительный параметр:
SessionAuthentication
Эта схема аутентификации использует бэкенд сессий Django по умолчанию для аутентификации. Сеансовая аутентификация подходит для клиентов AJAX, которые работают в том же сеансовом контексте, что и ваш сайт.
При успешной аутентификации SessionAuthentication
предоставляет следующие учетные данные.
request.user
будет экземпляром DjangoUser
.request.auth
будетNone
.
Ответы без аутентификации, которым отказано в разрешении, приведут к ответу HTTP 403 Forbidden
.
Если вы используете API в стиле AJAX с SessionAuthentication
, вам нужно убедиться, что вы включаете действительный CSRF токен для любых "небезопасных" вызовов HTTP методов, таких как PUT
, PATCH
, POST
или DELETE
запросы. Более подробную информацию смотрите в Django CSRF documentation.
Предупреждение: Всегда используйте стандартное представление входа Django при создании страниц входа. Это обеспечит надлежащую защиту ваших представлений входа.
Проверка CSRF в DRF работает несколько иначе, чем в стандартном Django, из-за необходимости поддерживать как сеансовую, так и несеансовую аутентификацию для одних и тех же представлений. Это означает, что только аутентифицированные запросы требуют CSRF-токенов, а анонимные запросы могут быть отправлены без CSRF-токенов. Такое поведение не подходит для представлений входа в систему, к которым всегда должна применяться проверка CSRF.
RemoteUserAuthentication
Эта схема аутентификации позволяет вам делегировать аутентификацию вашему веб-серверу, который устанавливает переменную окружения REMOTE_USER
.
Чтобы использовать его, вы должны иметь django.contrib.auth.backends.RemoteUserBackend
(или его подкласс) в настройке AUTHENTICATION_BACKENDS
. По умолчанию RemoteUserBackend
создает объекты User
для имен пользователей, которые еще не существуют. Чтобы изменить это и другое поведение, обратитесь к документации Django.
При успешной аутентификации RemoteUserAuthentication
предоставляет следующие учетные данные:
request.user
будет экземпляром DjangoUser
.request.auth
будетNone
.
Обратитесь к документации вашего веб-сервера за информацией о настройке метода аутентификации, например:
Пользовательская аутентификация
Чтобы реализовать собственную схему аутентификации, создайте подкласс BaseAuthentication
и переопределите метод .authenticate(self, request)
. Метод должен возвращать кортеж (user, auth)
, если аутентификация прошла успешно, или None
в противном случае.
В некоторых случаях вместо возврата None
вы можете захотеть вызвать исключение AuthenticationFailed
из метода .authenticate()
.
Как правило, вам следует придерживаться следующего подхода:
Если попытка аутентификации не была предпринята, верните
None
. Любые другие схемы аутентификации, которые также используются, будут проверены.Если попытка аутентификации была предпринята, но не удалась, вызовите исключение
AuthenticationFailed
. Ответ об ошибке будет возвращен немедленно, независимо от любых проверок разрешений и без проверки других схем аутентификации.
Вы можете также переопределить метод .authenticate_header(self, request)
. Если он реализован, он должен возвращать строку, которая будет использоваться в качестве значения заголовка WWW-Authenticate
в ответе HTTP 401 Unauthorized
.
Если метод .authenticate_header()
не переопределен, схема аутентификации будет возвращать ответы HTTP 403 Forbidden
, когда неаутентифицированному запросу будет отказано в доступе.
Примечание: Когда ваш пользовательский аутентификатор вызывается свойствами .user
или .auth
объекта запроса, вы можете увидеть, как AttributeError
преобразуется в WrappedAttributeError
. Это необходимо для того, чтобы исходное исключение не было подавлено доступом к внешнему свойству. Python не распознает, что AttributeError
исходит от вашего пользовательского аутентификатора, и вместо этого будет считать, что объект запроса не имеет свойства .user
или .auth
. Эти ошибки должны быть исправлены или иным образом обработаны вашим аутентификатором.
Пример
Следующий пример аутентифицирует любой входящий запрос как пользователя, указанного в имени пользователя в пользовательском заголовке запроса 'X-USERNAME'.
Пакеты сторонних производителей
Также доступны следующие пакеты сторонних производителей.
django-rest-knox
Библиотека Django-rest-knox предоставляет модели и представления для обработки аутентификации на основе токенов более безопасным и расширяемым способом, чем встроенная схема TokenAuthentication
- с учетом одностраничных приложений и мобильных клиентов. Она предоставляет токены для каждого клиента, а также представления для их генерации при предоставлении другой аутентификации (обычно базовой), для удаления токена (обеспечивая принудительный выход с сервера) и для удаления всех токенов (выход из всех клиентов, в которые вошел пользователь).
Django OAuth Toolkit
Пакет Django OAuth Toolkit обеспечивает поддержку OAuth 2.0 и работает с Python 3.4+. Пакет поддерживается jazzband и использует превосходный OAuthLib. Пакет хорошо документирован, хорошо поддерживается и в настоящее время является нашим рекомендованным пакетом для поддержки OAuth 2.0.
Установка и настройка
Установите с помощью pip
.
Добавьте пакет в INSTALLED_APPS
и измените настройки DRF.
Более подробную информацию можно найти в документации Django REST framework - Getting started.
Django REST framework OAuth
Пакет Django REST framework OAuth обеспечивает поддержку OAuth1 и OAuth2 для DRF.
Ранее этот пакет был включен непосредственно в DRF, но теперь поддерживается и сопровождается как пакет стороннего разработчика.
Установка и настройка
Установите пакет с помощью pip
.
Подробнее о настройке и использовании смотрите документацию по OAuth фреймворку Django REST для authentication и permissions.
JSON Web Token Authentication
JSON Web Token - это довольно новый стандарт, который можно использовать для аутентификации на основе токенов. В отличие от встроенной схемы TokenAuthentication, аутентификация JWT не требует использования базы данных для проверки токена. Пакет для JWT-аутентификации - djangorestframework-simplejwt, который предоставляет некоторые возможности, а также подключаемое приложение черного списка токенов.
Аутентификация Hawk HTTP
Библиотека HawkREST основана на библиотеке Mohawk и позволяет вам работать с подписанными запросами и ответами Hawk в вашем API. Hawk позволяет двум сторонам безопасно общаться друг с другом, используя сообщения, подписанные общим ключом. Она основана на HTTP MAC аутентификации доступа (которая была основана на части OAuth 1.0).
Аутентификация подписью HTTP
HTTP Signature (в настоящее время проект IETF) предоставляет способ достижения аутентификации происхождения и целостности сообщений HTTP. Подобно схеме Amazon's HTTP Signature scheme, используемой многими сервисами компании, она допускает безэталонную аутентификацию по каждому запросу. Elvio Toccalino поддерживает пакет djangorestframework-httpsignature (устаревший), который предоставляет простой в использовании механизм аутентификации HTTP Signature. Вы можете использовать обновленную версию-форк djangorestframework-httpsignature, которой является drf-httpsig.
Djoser
Djoser библиотека предоставляет набор представлений для обработки основных действий, таких как регистрация, вход в систему, выход из системы, сброс пароля и активация учетной записи. Пакет работает с пользовательской моделью пользователя и использует аутентификацию на основе токенов. Это готовая к использованию REST-реализация системы аутентификации Django.
django-rest-auth / dj-rest-auth
Эта библиотека предоставляет набор конечных точек REST API для регистрации, аутентификации (включая аутентификацию в социальных сетях), сброса пароля, получения и обновления данных пользователя и т.д. Имея эти конечные точки API, ваши клиентские приложения, такие как AngularJS, iOS, Android и другие, могут самостоятельно общаться с вашим бэкендом Django через REST API для управления пользователями.
В настоящее время существует два форка этого проекта.
Django-rest-auth - оригинальный проект, но в настоящее время не получает обновлений.
Dj-rest-auth - более новый форк проекта.
drf-social-oauth2
Drf-social-oauth2 - это фреймворк, который поможет вам аутентифицироваться у основных поставщиков социального oauth2, таких как Facebook, Google, Twitter, Orcid и др. Он генерирует токены в виде JWT с простой настройкой.
drfpasswordless
drfpasswordless добавляет (по мотивам Medium, Square Cash) поддержку беспарольного входа в схему TokenAuthentication платформы DRF. Пользователи входят в систему и регистрируются с помощью токена, отправленного на контактную точку, например, адрес электронной почты или номер мобильного телефона.
django-rest-authemail
django-rest-authemail предоставляет RESTful API интерфейс для регистрации и аутентификации пользователей. Для аутентификации используются адреса электронной почты, а не имена пользователей. Доступны конечные точки API для регистрации, проверки электронной почты при регистрации, входа в систему, выхода из системы, сброса пароля, проверки сброса пароля, изменения электронной почты, проверки изменения электронной почты, изменения пароля и детализации пользователя. Полностью функциональный пример проекта и подробные инструкции прилагаются.
Django-Rest-Durin
Django-Rest-Durin создана с идеей иметь одну библиотеку, которая делает аутентификацию токенов для нескольких Web/CLI/Mobile API клиентов через один интерфейс, но позволяет различную конфигурацию токенов для каждого API клиента, который потребляет API. Она обеспечивает поддержку нескольких токенов для каждого пользователя через пользовательские модели, представления, разрешения, которые работают с Django-Rest-Framework. Время истечения срока действия токена может быть разным для каждого API-клиента и настраивается через интерфейс администратора Django.
Более подробную информацию можно найти в Документации.
Last updated