Django Rest Framework обнаруживает AnonymousUser по запросам PUT - PullRequest
0 голосов
/ 19 июня 2020

У меня есть это представление

class OrderItemViewSet(viewsets.ModelViewSet):
  serializer_class = OrderItemSerializer

  def get_queryset(self):
    print('Current User', self.request.user, self.action)
    return OrderItem.objects.filter(order__owner=self.request.user.profile)

обратите внимание на print('Current User', self.request.user), которое я использовал для определения root проблемы.

urls.py

router.register('order_items', shopping_api.OrderItemViewSet, 'order_items')

Пока все хорошо ... Но когда я делаю запрос PUT;

    const response = await fetch(api.authurl+'/order_items/'+order_item.id+'/', {
      method: 'PUT',
      headers: api.httpHeaders,
      body: JSON.stringify(order_item)
    });

Эта ошибка появляется

AttributeError: 'AnonymousUser' object has no attribute 'profile'

Оператор печати идентифицирует их для GET затем запрос POST соответственно:

[19/Jun/2020 21:03:02] "GET /sellers/3/ HTTP/1.1" 200 196
Current User AD list
[19/Jun/2020 21:03:03] "GET /order_items/ HTTP/1.1" 200 1046
Current User AnonymousUser update

Итак, у меня есть основания полагать, что когда я делаю запрос на получение, аутентифицированный пользователь обнаруживается, но с PUT он внезапно становится анонимным. Я сомневаюсь, что мне нужно правильно выполнять аутентификацию внешнего интерфейса? например, наличие авторизации с токеном в моих заголовках в запросе. Поскольку у меня этот запрос GET работает нормально.

EDIT: добавление SellerViewSet:

class SellerViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
  queryset = Seller.objects.all()
  serializer_class = SellerSerializer

1 Ответ

0 голосов
/ 19 июня 2020
Схема аутентификации

DRF использует серверную часть сеанса Django по умолчанию для аутентификации, если вы используете API стиля AJAX с SessionAuthentication, вам необходимо убедиться, что вы включили действительный токен CSRF для любого " небезопасные "вызовы методов HTTP, такие как PUT, PATCH, POST or DELETE запросы (документы DRF)

IsAuthenticated требуют наличия как объекта request.user, так и пользователя (is_authenticated).

class IsAuthenticated(BasePermission):
    """
    Allows access only to authenticated users.
    """

    def has_permission(self, request, view):
        return bool(request.user and request.user.is_authenticated)

вам нужно установить заголовок X-CSRFToken для запроса заголовка для следующего запроса, чтобы сервер знал, кто вы

 var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();
 xhr.setRequestHeader("X-CSRFToken", csrftoken);

// fetch
 headers:{
  'X-CSRFToken': jQuery("input[name=csrfmiddlewaretoken]").val()
}

https://www.django-rest-framework.org/api-guide/authentication/#sessionauthentication

...