0

I have this viewset

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)

take note of the print('Current User', self.request.user) I have used that to identify the root of the problem.

urls.py

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

So far so good... But when I make a PUT request;

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

This error shows up

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

The print statement identifies these for a GET then a POST request respectively:

[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

So I have reason to believe that when I make a get request, the authenticated user is detected, but with a PUT it's suddenly Anonymous. I doubt I have to make frontend authentication right? e.g having Authorization with a token in my headers in the request. Since I have that GET request doing fine.

EDIT: adding SellerViewSet:

class SellerViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
  queryset = Seller.objects.all()
  serializer_class = SellerSerializer
Storm Llamas
  • 119
  • 1
  • 2
  • 10
  • 1
    Yes, you have to make frontend authentication. You could also provide authentication_classes to your OrderItemViewSet, so if there is no token provided, your view will inform you that you have to authenticate first. – token Jun 19 '20 at 12:37
  • I was hoping it wasn't true. Why would a get request return an authenticated user, while a PUT would not? Follow-up question: Would there be another way to only allow users who own the object to have access to http requests to it? I am having permission problems as well, you see. – Storm Llamas Jun 19 '20 at 12:42
  • Look at your logs. Even your GET /order_items/ returns AnonymousUser. For permissions: you could write your own BasePermission. There are many examples, so it won't be hard to find them. – token Jun 19 '20 at 12:53
  • GET returns AD which is my user. Also I've added IsAuthenticated permission class and I can still make a GET request. I have found some examples, but I still have the same issue – Storm Llamas Jun 19 '20 at 12:58
  • [19/Jun/2020 20:17:30] "GET /order_items/ HTTP/1.1" 200 1060 <- it returns AnonymousUser – token Jun 19 '20 at 13:00
  • Show your sellers view aswell. If it works, lets compare them. – token Jun 19 '20 at 13:01
  • Made edits above, as you can see the log you pointed was infact a PUT request or 'update' in action. Although I do admit that was a bit confusing, and evidently I wasn't even making a GET request to a specific orderItem instance, It was a GET for a list action type. Sellers view on the other hand is very basic viewset – Storm Llamas Jun 19 '20 at 13:11

1 Answers1

0

DRF authentication scheme uses Django's default session backend for authentication, if you're using an AJAX style API with SessionAuthentication, you'll need to make sure you include a valid CSRF token for any "unsafe" HTTP method calls, such as PUT, PATCH, POST or DELETE requests(DRF docs)

IsAuthenticated requires the both the request.user object and the user logged in(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)

you need set header X-CSRFToken to request header for next request so that the server knows who you are

 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

minglyu
  • 2,958
  • 2
  • 13
  • 32