🔖 Справочник — Урок 40

← К оглавлению урока

⚡ Быстрый справочник

# settings.py — TokenAuthentication
INSTALLED_APPS = ['rest_framework', 'rest_framework.authtoken']
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework.authentication.TokenAuthentication'],
    'DEFAULT_PERMISSION_CLASSES': ['rest_framework.permissions.IsAuthenticated'],
}
python manage.py migrate  # создать таблицу токенов

# Получение токена (POST)
Authorization: Token <key>

# settings.py — JWT
pip install djangorestframework-simplejwt
REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework_simplejwt.authentication.JWTAuthentication']}
# Заголовок
Authorization: Bearer <access_token>

Классы аутентификации DRF

Класс Import путь Заголовок запроса Когда применять
SessionAuthentication rest_framework.authentication Cookie (автоматически) Django web-приложения с формами
BasicAuthentication rest_framework.authentication Authorization: Basic base64(user:pass) Тестирование, только с HTTPS
TokenAuthentication rest_framework.authentication Authorization: Token <key> REST API, мобильные приложения
RemoteUserAuthentication rest_framework.authentication HTTP заголовок REMOTE_USER SSO, корпоративные системы
JWTAuthentication rest_framework_simplejwt.authentication Authorization: Bearer <token> Современные REST API, микросервисы

Классы разрешений DRF

Класс Поведение Коды ответа при отказе
AllowAny Разрешено всем
IsAuthenticated Только авторизованные пользователи 401 / 403
IsAdminUser Только is_staff=True 401 / 403
IsAuthenticatedOrReadOnly Чтение для всех, запись — только авторизованным 401 / 403 (для не-безопасных методов)
DjangoModelPermissions Права Django-модели (add/change/delete/view) 403

Настройка settings.py

SessionAuthentication (по умолчанию в DRF)

# settings.py
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
}

TokenAuthentication

# settings.py
INSTALLED_APPS = [
    ...
    'rest_framework',
    'rest_framework.authtoken',  # обязательно!
]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
}
# После изменения settings.py
python manage.py migrate  # создаёт таблицу authtoken_token

JWT (Simple JWT)

pip install djangorestframework-simplejwt
# settings.py
from datetime import timedelta

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],
}

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
    'ROTATE_REFRESH_TOKENS': False,
    'ALGORITHM': 'HS256',
}
# urls.py
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView

urlpatterns = [
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]

Настройка аутентификации на уровне представления

# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import TokenAuthentication, BasicAuthentication
from rest_framework.permissions import IsAuthenticated, IsAdminUser, AllowAny

# TokenAuthentication для конкретного представления
class ProtectedView(APIView):
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticated]

    def get(self, request):
        return Response({"user": request.user.username})

# Публичное представление (переопределяет глобальные настройки)
class PublicView(APIView):
    permission_classes = [AllowAny]

    def get(self, request):
        return Response({"message": "Доступно всем"})

# Только для администраторов
class AdminView(APIView):
    permission_classes = [IsAdminUser]

    def get(self, request):
        return Response({"message": "Только для admin"})

Работа с токенами (TokenAuthentication)

Создание токена вручную

from rest_framework.authtoken.models import Token
from django.contrib.auth.models import User

user = User.objects.get(username='alice')
token, created = Token.objects.get_or_create(user=user)
print(token.key)  # 'e282c0176725bc6cca14396b5b7ab9affc440244'

URL для получения токена

# urls.py
from rest_framework.authtoken.views import obtain_auth_token

urlpatterns = [
    path('api-token-auth/', obtain_auth_token, name='api_token_auth'),
]

Запрос токена через curl

curl -X POST http://127.0.0.1:8000/api-token-auth/ \
  -d "username=alice&password=secret123"

# Ответ:
{"token": "e282c0176725bc6cca14396b5b7ab9affc440244"}

Использование токена

curl http://127.0.0.1:8000/api/protected/ \
  -H "Authorization: Token e282c0176725bc6cca14396b5b7ab9affc440244"

Полезные команды Django

# Создание пользователя для тестов
python manage.py createsuperuser

# Применение миграций (для authtoken)
python manage.py migrate

# Shell — создание токена вручную
python manage.py shell
>>> from rest_framework.authtoken.models import Token
>>> from django.contrib.auth.models import User
>>> user = User.objects.get(username='admin')
>>> Token.objects.create(user=user)