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
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