💻 Примеры — Урок 40
⚡ Минимальный пример: защищённый эндпоинт с 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'],
}
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
class MeView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request):
return Response({"username": request.user.username})
# urls.py
from rest_framework.authtoken.views import obtain_auth_token
urlpatterns = [
path('api/token/', obtain_auth_token),
path('api/me/', MeView.as_view()),
]
Пример 1: BasicAuthentication
Простейшая настройка для тестирования — только с HTTPS в production.
settings.py
# settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
views.py
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import IsAuthenticated
class ProtectedDataView(APIView):
authentication_classes = [BasicAuthentication]
permission_classes = [IsAuthenticated]
def get(self, request):
return Response({
"message": "Hello, authenticated user!",
"user": request.user.username,
})
urls.py
# urls.py
from django.urls import path
from .views import ProtectedDataView
urlpatterns = [
path('protected/', ProtectedDataView.as_view(), name='protected-data'),
]
Тестирование через Postman
- Создайте GET-запрос к
http://127.0.0.1:8000/protected/ - Вкладка Authorization → Type: Basic Auth
- Введите Username и Password
- Postman автоматически добавит заголовок
Authorization: Basic dXNlcjpwYXNz
⚠️ В браузере можно передать учётные данные через URL:
http://alice:secret@127.0.0.1:8000/protected/ — только для тестирования, небезопасно.
Пример 2: TokenAuthentication — полный цикл
Получение токена через POST-запрос и использование в защищённых эндпоинтах.
settings.py
# settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework.authtoken', # ← обязательно
'myapp',
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
Миграции
python manage.py migrate
# Создаёт таблицу authtoken_token в базе данных
views.py
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
class ProtectedDataView(APIView):
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
def get(self, request):
return Response({
"message": "Hello, authenticated user!",
"user": request.user.username,
"email": request.user.email,
})
urls.py
# urls.py
from django.urls import path
from rest_framework.authtoken.views import obtain_auth_token
from .views import ProtectedDataView
urlpatterns = [
path('api-token-auth/', obtain_auth_token, name='api_token_auth'),
path('protected/', ProtectedDataView.as_view(), name='protected-data'),
]
Шаги тестирования через Postman
Шаг 1: Получение токена
- Метод: POST, URL:
http://127.0.0.1:8000/api-token-auth/ - Body → form-data:
username=admin,password=secret123 - Нажмите Send. Ответ:
{"token": "e282c0176725bc6cca14396b5b7ab9affc440244"}
Шаг 2: Использование токена
- Метод: GET, URL:
http://127.0.0.1:8000/protected/ - Headers:
Authorization: Token e282c0176725bc6cca14396b5b7ab9affc440244 - Нажмите Send. Ответ:
{"message": "Hello, authenticated user!", "user": "admin"}
Пример 3: JWT (Simple JWT)
Современный подход с access + refresh токенами.
Установка
pip install djangorestframework-simplejwt
settings.py
# settings.py
from datetime import timedelta
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
}
urls.py
# urls.py
from django.urls import path
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
from .views import ProtectedDataView
urlpatterns = [
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path('api/protected/', ProtectedDataView.as_view(), name='protected'),
]
views.py
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
class ProtectedDataView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request):
return Response({
"message": "Hello, authenticated user!",
"user": request.user.username,
})
Тестирование через Postman
Шаг 1: Получение JWT
- POST
http://127.0.0.1:8000/api/token/ - Body → form-data:
username=admin,password=secret123 - Ответ:
{"access": "eyJhbGci...", "refresh": "eyJhbGci..."}
Шаг 2: Доступ к защищённому ресурсу
- GET
http://127.0.0.1:8000/api/protected/ - Headers:
Authorization: Bearer eyJhbGciOiJIUzI1NiIs... - Ответ:
{"message": "Hello, authenticated user!", "user": "admin"}
Шаг 3: Обновление истёкшего токена
- POST
http://127.0.0.1:8000/api/token/refresh/ - Body → form-data:
refresh=eyJhbGci... (refresh-токен) - Ответ:
{"access": "eyJhbGci... (новый access-токен)"}
Пример 4: смешанная аутентификация и разные разрешения
# views.py — несколько представлений с разными правами
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser, AllowAny, IsAuthenticatedOrReadOnly
class PublicNewsView(APIView):
"""Новости доступны всем без аутентификации"""
permission_classes = [AllowAny]
def get(self, request):
return Response({"news": ["Новость 1", "Новость 2"]})
class UserProfileView(APIView):
"""Профиль — только для аутентифицированных"""
permission_classes = [IsAuthenticated]
def get(self, request):
return Response({
"username": request.user.username,
"email": request.user.email,
})
class AdminDashboardView(APIView):
"""Дашборд — только для staff-пользователей"""
permission_classes = [IsAdminUser]
def get(self, request):
return Response({"stats": {"users": 42, "posts": 128}})
class ArticleView(APIView):
"""Статьи: читать могут все, писать — только авторизованные"""
permission_classes = [IsAuthenticatedOrReadOnly]
def get(self, request):
return Response({"articles": ["Статья 1", "Статья 2"]})
def post(self, request):
# Сюда попадут только аутентифицированные
return Response({"created": request.data.get("title")}, status=201)