Декоратор csrf_exempt
Декоратор csrf_exempt применяется к функциям представления или классам и отключает для них проверку CSRF-токена. Это может быть полезно при создании API-эндпоинтов, которые принимают запросы от внешних сервисов, не поддерживающих CSRF-токены. Декоратор находится в модуле django.views.decorators.csrf и используется для временного отключения защиты на отдельных представлениях.
Синтаксис
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def view_function(request):
# обработка запроса
return HttpResponse("OK")
Пример . Для функции представления
Давайте создадим представление, которое принимает POST-запросы без CSRF-токена:
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
import json
@csrf_exempt
def api_webhook(request):
if request.method == 'POST':
try:
data = json.loads(request.body)
res = {
'status': 'success',
'data': data
}
return JsonResponse(res)
except json.JSONDecodeError:
return JsonResponse(
{'error': 'Invalid JSON'},
status=400
)
return JsonResponse(
{'error': 'Method not allowed'},
status=405
)
Результат выполнения кода при успешном запросе:
{
"status": "success",
"data": {"message": "Hello from webhook"}
}
Пример . Для классов представлений
Декоратор csrf_exempt также можно использовать с классовыми представлениями через метод dispatch:
from django.http import JsonResponse
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
@method_decorator(csrf_exempt, name='dispatch')
class WebhookAPIView(View):
def post(self, request):
# обработка POST-запроса
res = {
'status': 'ok',
'message': 'Webhook received'
}
return JsonResponse(res)
def get(self, request):
res = {
'status': 'ok',
'message': 'GET request allowed without CSRF'
}
return JsonResponse(res)
Результат выполнения кода при GET-запросе:
{
"status": "ok",
"message": "GET request allowed without CSRF"
}
Пример . Работа с внешним API
Рассмотрим реальный пример, где необходимо принять данные от внешнего сервиса:
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from myapp.models import WebhookLog
@csrf_exempt
@require_POST
def external_callback(request):
try:
# Сохраняем данные от внешнего сервиса
webhook_data = request.POST.dict()
WebhookLog.objects.create(
source='external_api',
payload=webhook_data
)
return HttpResponse("Webhook processed successfully", status=200)
except Exception as e:
return HttpResponse(f"Error: {str(e)}", status=400)
Результат выполнения кода при успешной обработке:
"Webhook processed successfully"
Внимание при использовании
При использовании декоратора csrf_exempt важно помнить о безопасности. Отключать CSRF-защиту следует только для представлений, которые обрабатывают запросы от доверенных источников. Для обычных форм и внутренних API лучше оставлять защиту включенной. Также рекомендуется комбинировать csrf_exempt с другими декораторами, например require_POST или require_http_methods, чтобы ограничить допустимые методы запросов.
Смотрите также
-
декоратор
csrf_protect,
который принудительно включает CSRF-защиту для представления -
декоратор
require_POST,
который разрешает только POST-запросы к представлению -
декоратор
require_GET,
который разрешает только GET-запросы к представлению -
декоратор
require_http_methods,
который ограничивает допустимые HTTP-методы для представления