Официальная оригинальная ссылка
Эта серия статей адрес github
Пожалуйста, укажите источник
Аутентификация
Аутентификация — это механизм связывания входящего запроса с набором идентифицирующих учетных данных, таких как запрашивающий пользователь или подписанный им токен. Затем эти учетные данные могут использоваться политиками разрешений и ограничений, чтобы определить, следует ли разрешить запрос.
Платформа REST предоставляет множество готовых схем аутентификации, а также позволяет реализовывать собственные схемы.
Аутентификация всегда выполняется в начале представления, перед выполнением проверок разрешений и ограничений и до того, как будет разрешено выполнение любого другого кода.
request.user
Свойство обычно устанавливается вcontrib.auth
упаковкаUser
Экземпляр класса.
request.auth
Атрибут используется для другой аутентификационной информации, например, его можно использовать для представления запроса на подписанный токен аутентификации.
Уведомление:не забудьте,Сама аутентификация не (Разрешить или не позволяет) входящие запросы, который просто определяет учетные данные для запроса.
Как определить аутентификацию
Схемы аутентификации всегда определяются как список классов. Платформа REST попытается пройти аутентификацию с каждым классом в списке и будет использовать возвращаемое значение первого класса, который успешно прошел аутентификацию, чтобы установитьrequest.user
иrequest.auth
.
Если нет класса для аутентификации, он будетrequest.user
Установить какdjango.contrib.auth.models.AnonymousUser
экземпляр и будетrequest.auth
Установить какNone
.
можно использоватьUNAUTHENTICATED_USER
иUNAUTHENTICATED_TOKEN
Установите модификацию неаутентифицированных запросовrequest.user
иrequest.auth
значение .
Настроить схему аутентификации
Можно использовать схему аутентификации по умолчанию.DEFAULT_AUTHENTICATION_CLASSES
настройка Глобальная настройка. Например.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
)
}
Вы также можете использоватьAPIView
Представление класса, которое устанавливает схему проверки подлинности для каждого представления или для каждого набора представлений.
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
class ExampleView(APIView):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'user': unicode(request.user), # `django.contrib.auth.User` instance.
'auth': unicode(request.auth), # None
}
return Response(content)
или если вы будете@api_view
Декораторы используются с представлениями, основанными на функциях.
@api_view(['GET'])
@authentication_classes((SessionAuthentication, BasicAuthentication))
@permission_classes((IsAuthenticated,))
def example_view(request, format=None):
content = {
'user': unicode(request.user), # `django.contrib.auth.User` instance.
'auth': unicode(request.auth), # None
}
return Response(content)
Несанкционированные и запрещенные ответы
Существует два разных кода ошибки, которые могут быть уместны, когда запрос, не прошедший проверку подлинности, отклонен.
- [HTTP 401 Unauthorized][http401]
- [HTTP 403 Permission Denied][http403]
Ответы HTTP 401 всегда должны содержатьWWW-Authenticate
заголовок, который указывает клиенту, как пройти аутентификацию. Ответ HTTP 403 не содержитWWW-Authenticate
заголовок.
Какой ответ будет использоваться, зависит от схемы аутентификации. Хотя несколько схем аутентификации могут быть использованы, только одна схема может быть использована для определения типа ответа.Используйте первый класс проверки подлинности, установленный в представлении, при определении типа ответа..
Обратите внимание, что когда запрос может быть успешно аутентифицирован, он все равно может быть отклонен из-за разрешений, и в этом случае всегда будет использоваться403 Permission Denied
ответ, независимо от схемы аутентификации.
Конкретная конфигурация Apache mod_wsgi
Обратите внимание, что при развертывании в Apache с использованием mod_wsgi заголовок авторизации по умолчанию не передается в приложения WSGI, поскольку предполагается, что аутентификация будет обрабатываться Apache, а не на уровне приложения.
Если вы выполняете развертывание в Apache и используете любую аутентификацию, не основанную на сеансе, вам необходимо явно настроить mod_wsgi для передачи необходимых заголовков в приложение. Это можно сделать, указав в соответствующем контекстеWSGIPassAuthorization
директиву и установить ее на'On'
Что нужно сделать.
# this can go in either server config, virtual host, directory or .htaccess
WSGIPassAuthorization On
Справочник по API
BasicAuthentication
Эта схема аутентификации использует базовую аутентификацию HTTP и подписывается на основе имени пользователя и пароля. Обычная аутентификация обычно подходит только для тестирования.
В случае успешной аутентификацииBasicAuthentication
Будут предоставлены следующие учетные данные.
-
request.user
ДжангоUser
сила. -
request.auth
даNone
.
Отклонение неаутентифицированных ответов приведет кHTTP 401 Unauthorized
ответ и соответствующий заголовок WWW-Authenticate. Например:
WWW-Authenticate: Basic realm="api"
Уведомление:Если вы используете в производствеBasicAuthentication
, вы должны убедиться, что ваш API доступен только черезhttps
доступ. Вы также должны убедиться, что ваш API-клиент всегда будет повторно запрашивать имя пользователя и пароль при входе в систему и никогда не сохранять эти данные в постоянном хранилище.
TokenAuthentication
Эта схема аутентификации использует простую схему аутентификации HTTP на основе токенов. Проверка подлинности с помощью токена работает с архитектурами клиент-сервер, такими как собственные настольные и мобильные клиенты.
нужно использоватьTokenAuthentication
схемы, вам нужно настроить класс аутентификации, чтобы он содержалTokenAuthentication
, И вINSTALLED_APPS
Также включается в настройкахrest_framework.authtoken
:
INSTALLED_APPS = (
...
'rest_framework.authtoken'
)
Уведомление:Обязательно запустите после изменения настроекmanage.py migrate
.rest_framework.authtoken
Приложение обеспечивает миграцию базы данных Django.
Вам также необходимо создать токен для вашего пользователя.
from rest_framework.authtoken.models import Token
token = Token.objects.create(user=...)
print token.key
Для аутентификации клиента ключ токена должен содержаться вAuthorization
в заголовке HTTP. Перед ключевым словом должен стоять строковый литерал "Token" с пробелом, разделяющим две строки. Например:
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
Уведомление:Если вы хотите использовать разные ключевые слова в заголовке (например,Bearer
), просто подклассTokenAuthentication
и установитьkeyword
переменная класса.
В случае успешной аутентификацииTokenAuthentication
Будут предоставлены следующие учетные данные.
-
request.user
ДжангоUser
Пример. -
request.auth
Являетсяrest_framework.authtoken.models.Token
пример.
Отклонение неаутентифицированных ответов приведет кHTTP 401 Unauthorized
ответ и соответствующий заголовок WWW-Authenticate. Например:
WWW-Authenticate: Token
curl
Инструменты командной строки могут быть полезны для тестирования API с аутентификацией по токену. Например:
curl -X GET http://127.0.0.1:8000/api/example/ -H 'Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b'
Уведомление:Если вы используете в производствеTokenAuthentication
, вы должны убедиться, что ваш API может пройти толькоhttps
доступ.
сгенерировать токен
с помощью сигналов
Если вы хотите, чтобы у каждого пользователя был автоматически сгенерированный токен, просто запишитеpost_save
сигнал.
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
Обратите внимание, что вам нужно обязательно поместить этот фрагмент в установленныйmodels.py
Модуль или другое место, которое Django импортирует при запуске.
Если вы уже создали некоторых пользователей, вы можете сгенерировать токены для всех существующих пользователей, например:
from django.contrib.auth.models import User
from rest_framework.authtoken.models import Token
for user in User.objects.all():
Token.objects.get_or_create(user=user)
Предоставляя конечную точку API
использоватьTokenAuthentication
, вы можете предоставить клиентам механизм получения токена для данного имени пользователя и пароля. Платформа REST предоставляет встроенное представление для поддержки такого поведения. Чтобы использовать его, пожалуйстаobtain_auth_token
просмотреть ваш URLconf:
from rest_framework.authtoken import views
urlpatterns += [
url(r'^api-token-auth/', views.obtain_auth_token)
]
Обратите внимание, что URL-часть шаблона может быть чем угодно.
Когда данные формы действительны или JSONusername
иpassword
Когда поле публикуется в представлении,obtain_auth_token
Представление вернет ответ JSON:
{ 'token' : '9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b' }
Обратите внимание, что по умолчаниюobtain_auth_token
Представления явно используют запросы и ответы JSON вместо заданных вами классов отрисовщика и парсера по умолчанию.
По умолчанию никакие разрешения или ограничения не применяются кobtain_auth_token
Посмотреть.如果您希望应用 throttling ,则需要重写视图类,并使用throttle_classes
свойства содержат их.
если вам нужно настроитьobtain_auth_token
вид, вы можете наследовать отObtainAuthToken
Просмотрите класс, чтобы реализовать и использовать его в своей конфигурации URL.
Например, вы можете вернуть превышениеtoken
Дополнительная информация о пользователе для значения:
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
class CustomAuthToken(ObtainAuthToken):
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data,
context={'request': request})
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user)
return Response({
'token': token.key,
'user_id': user.pk,
'email': user.email
})
иurls.py
:
urlpatterns += [
url(r'^api-token-auth/', CustomAuthToken.as_view())
]
Используйте админку Джанго
Токены также можно создавать вручную через интерфейс администратора. Если вы используете большую базу пользователей, мы рекомендуем вамTokenAdmin
класс, который нужно исправить, чтобы настроить его по мере необходимости, а точнее, будетuser
Поле объявлено какraw_field
.
your_app/admin.py
:
from rest_framework.authtoken.admin import TokenAdmin
TokenAdmin.raw_id_fields = ('user',)
Использование команды Django manage.py
Начиная с версии 3.6.4, токен пользователя можно сгенерировать с помощью следующей команды:
./manage.py drf_create_token <username>
Эта команда вернет токен API для данного пользователя или создаст его, если он не существует:
Generated token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b for user user1
Если вы хотите перегенерировать токен (например, он был слит), вы можете передать дополнительный параметр:
./manage.py drf_create_token -r <username>
SessionAuthentication
Эта схема аутентификации использует серверную часть сеанса Django по умолчанию для аутентификации. Аутентификация сеанса работает с клиентами AJAX, работающими в той же среде сеанса, что и ваш веб-сайт.
Если авторизация прошла успешно, тоSessionAuthentication
Предоставляются следующие учетные данные.
-
request.user
ДжангоUser
пример. -
request.auth
даNone
.
Отклонение неаутентифицированных ответов приведет кHTTP 403 Forbidden
отклик.
Если вы используете API в стиле AJAX в SessionAuthentication, вам необходимо убедиться, что любой «небезопасный» HTTP-метод вызывается (например,PUT
,PATCH
,POST
илиDELETE
request) содержит действительный токен CSRF.
предупреждать: вы всегда должны использовать стандартный вид входа Django при создании страниц входа. Это обеспечит надлежащую защиту вашего входа в систему.
Аутентификация CSRF в среде REST немного отличается от стандартной Django, поскольку необходимо поддерживать как аутентификацию на основе сеанса, так и аутентификацию без сеанса. Это означает, что только аутентифицированные запросы требуют токена CSRF, а анонимные запросы можно отправлять без токена CSRF. Это поведение не применяется к представлениям входа в систему, где всегда должна применяться проверка CSRF.
RemoteUserAuthentication
Эта схема аутентификации позволяет делегировать аутентификацию вашему веб-серверу, который устанавливаетREMOTE_USER
переменные окружения.
Чтобы использовать его, вы должныAUTHENTICATION_BACKENDS
в настройкахdjango.contrib.auth.backends.RemoteUserBackend
(или подкласс). по умолчанию,RemoteUserBackend
Создать для имени пользователя, которое не существуетUser
объект. Чтобы изменить это и другое поведение, обратитесь к документации Django.
В случае успешной аутентификацииRemoteUserAuthentication
Будут предоставлены следующие учетные данные:
-
request.user
ДжангоUser
пример. -
request.auth
даNone
.
Для получения информации о настройке методов аутентификации см. документацию вашего веб-сервера, например:
пользовательская аутентификация
Чтобы реализовать пользовательскую схему аутентификации, наследуйтеBaseAuthentication
и переписать.authenticate(self, request)
метод. Если аутентификация прошла успешно, метод должен вернуть(user, auth)
2-кортеж из , иначе возвратNone
.
В некоторых случаях вы можете захотеть.authenticate()
броски методаAuthenticationFailed
исключение вместо возвратаNone
.
Обычно подход, который вы должны использовать, следующий:
- Возвращает, если попытка аутентификации не предпринималась
None
. Любая другая используемая схема аутентификации по-прежнему будет проверяться. - Повышение, если попытка аутентификации не удалась
AuthenticationFailed
аномальный. Независимо от того, проверяются ли какие-либо разрешения, ответ об ошибке будет возвращен немедленно, и никакие другие схемы проверки подлинности не проверяются.
ты тожеМожетпереписать.authenticate_header(self, request)
метод. Если он реализован, он должен возвращать строку, которая будет использоваться какHTTP 401 Unauthorized
Значение заголовка WWW-Authenticate в ответе.
если не покрыт.authenticate_header()
Метод, затем, когда неанатурные запросы отказаны доступом, схема аутентификации возвращаетHTTP 403 Forbidden
отклик.
Note:когда объект запроса.user
или.auth
свойство для вызова вашего пользовательского аутентификатора, вы можете увидетьAttributeError
в видеWrappedAttributeError
повторно повышается. Это необходимо для предотвращения подавления исходного исключения при доступе к внешнему свойству. Питон не распознаетAttributeError
Из вашего пользовательского аутентификатора, но он не предполагает объекта запроса.user
или.auth
Атрибуты. Эти ошибки должны быть исправлены или иным образом обработаны вашим валидатором.
взять каштан
В следующем примере будет выполняться проверка подлинности любого входящего запроса на основе имени пользователя в пользовательском заголовке запроса с именем «X_USERNAME».
from django.contrib.auth.models import User
from rest_framework import authentication
from rest_framework import exceptions
class ExampleAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
username = request.META.get('X_USERNAME')
if not username:
return None
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
raise exceptions.AuthenticationFailed('No such user')
return (user, None)