Как запретить пользователю изменять данные с помощью Django DRF
Мои конечные точки API доступны браузеру через Django DRF, что, как я знаю, является нормальным явлением. Однако основная проблема заключается в том, что кто-то может выполнить любую операцию, которую может выполнить мой API, не проходя через мое приложение. У меня есть проверка подлинности для моих конечных точек, но пользователь может, например, удалить платежные записи или опубликовать неверные данные и другие подобные операции. Я использую JWT auth, но если пользователь уже зарегистрирован в моем приложении в том же браузере, он может это увидеть. Есть ли какой-нибудь способ предотвратить это?
Установите пользовательский заголовок во всех ваших запросах к интерфейсному API (например, X-From-Frontend: true) и проверьте его на сервере. Напишите пользовательское промежуточное программное обеспечение для проверки заголовка.
Во внешнем интерфейсе,
fetch("/api/endpoint", {
headers: {
"Authorization": "Bearer <token>",
"X-From-Frontend": "true"
}
})
В Дайнго,
class FrontendHeaderRequiredMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if request.path.startswith("/api/") and request.method in ["POST", "PUT", "DELETE"]:
if request.headers.get("X-From-Frontend") != "true":
return JsonResponse({"detail": "Forbidden: Invalid source."}, status=403)
return self.get_response(request)
это установит заголовок X-From-Frontend во внешнем интерфейсе и проверит его в пользовательском промежуточном программном обеспечении django.
таким образом, вы можете разрешить доступ к вашим API только запросам от вашего интерфейса
Во-первых, я советую вам указать разрешенные операции в каждом API (Post, Get, ...).
Кроме того, я предлагаю внедрить новый уникальный для вас заголовок, который вы можете сохранить в своей базе данных, и это для каждого из ваших приложений или интерфейсов. Затем внедрите промежуточное программное обеспечение, которое проверяет, что запросы поступают именно из тех интерфейсов, которые есть в вашей базе данных.
from django.db import models
import uuid
class AuthorizedInterface(models.Model):
name = models.CharField()
unique_identifier = models.UUIDField(default=uuid.uuid4, editable=False, unique=True, help_text="Unique identifier of the interface")
is_active = models.BooleanField(default=True, help_text="Indicates if this interface is active and authorized")
unique_identifier
это значение вы можете использовать в качестве значения вашего заголовка.
для вашего промежуточного программного обеспечения:
from django.utils.deprecation import MiddlewareMixin
from django.http import HttpResponseForbidden
from .models import AuthorizedInterface
class VerifyInterfaceOriginMiddleware(MiddlewareMixin):
def process_request(self, request):
origin_header = request.META.get('HTTP_X_INTERFACE_ID') # Custom header name
if not origin_header:
return HttpResponseForbidden("Missing origin header.")
try:
interface = AuthorizedInterface.objects.get(unique_identifier=origin_header, is_active=True)
request.authorized_interface = interface # Optional: store the interface in the request
return None
except AuthorizedInterface.DoesNotExist:
return HttpResponseForbidden("Request origin not authorized.")
и для вашего приложения, например
fetch("/api/endpoint", {
headers: {
'Authorization': 'Bearer <token>',
'X-INTERFACE-ID': 'your-application-unique-id' // Replace with the actual ID
}
}
надеюсь, это поможет вам.
основная проблема заключается в том, что кто-то может выполнить любую операцию, которую может выполнить мой API
Вы сами сказали, в чем проблема. Вам нужна надлежащая авторизация и система разрешений.
Вашим пользователям должно быть разрешено выполнять только определенные операции.
Никогда не следует доверять входящим данным. Всегда выполняйте надлежащую проверку на сервере.
В моем приложении у нас есть роли пользователей и разрешения, например:
- Программа просмотра может использовать только список конечных точек и подробные сведения о них
- РЕДАКТОР также может использовать функцию обновления и создавать конечные точки
и т.д.
Проверьте: https://www.django-rest-framework.org/api-guide/permissions/