I am having issues using the DRF SessionAuthentication with views defined as ModelViewSets. The "LoginRequiredMixin" works fine in generics views, but I really don't like those as they require me to define all the urls manually and set them in the proper order. Very tedious when ViewSets allow you to define routes way more neatly.
I have tried using the "@login_required" decorator following Django's doc authentication login(), but it doesn't accept it. Have tried specifying the authentication_class SessionAuthentication in my ViewSet but to no avail, following those posts:
Current FooBar_views.py file. The only way I have here so far to make sure a user is authenticated, is to check his JWT provided in the headers of his http request.
foobar_vews.py with ViewSets
# @login_required not being accepted when imported
class FooBarViewSet(viewsets.ModelViewSet):
"""
Foo Bar ViewSet calling various serializers depending on request type (GET, PUT etc.)
"""
# Trying to filter FooBars list by status: Exluding unwanted ones
queryset = FooBar.objects.exclude(status__name = 'SOLD').exclude(status__name = 'DELETED').order_by('id').reverse()
# mapping serializer into the action
serializer_classes = {
'list': FooBarIndexSerializer,
'retrieve': FooBarDetailsSerializer,
'create': FooBarCreateSerializer,
}
# Your default serializer
default_serializer_class = FooBarIndexSerializer
def get_serializer_class(self):
"""
Method to detect request type (GET, PUT etc.) and select corresponding serializer.
"""
return self.serializer_classes.get(self.action, self.default_serializer_class)
# TODO: Move this to the permissions.py file?
def get_permissions(self):
"""
Method to apply permissions depending on request type (GET, PUT etc.)
"""
if self.request.method == 'GET':
return [permissions.DjangoModelPermissionsOrAnonReadOnly()]
elif self.request.method == 'POST':
return [permissions.IsAuthenticated(), IsArtist()]
else: # PUT, PATCH, DELETE
return [permissions.IsAuthenticated(), IsOwner()]
Equivalent I'd need to define if using generics views. As can be seen, I don't need to add any "isAuthenticated" permission class as the "LoginRequiredMixin" checks that the user is logged, by checking the sessionId and CSRFToken.
Problem here, I need to manually define all the corresponding urls in the url.py file. Which is tedious and gets confusing as the FooBarListView and FooBarCreateView should normally be the same url, but different requests surch as GET and POST.
foobar_vews.py with generic views
class FooBarListView(LoginRequiredMixin, ListAPIView):
queryset = FooBar.objects.all()
serializer_class = FooBarIndexSerializer
class FooBarDetailView(LoginRequiredMixin, RetrieveAPIView):
queryset = FooBar.objects.all()
serializer_class = FooBarDetailsSerializer
# TODO: Voir pour passer aux modelViews
class FooBarCreateView(LoginRequiredMixin, CreateAPIView):
queryset = FooBar.objects.all()
serializer_class = FooBarCreateSerializer
permission_classes = [IsOwner]
def perform_create(self, serializer):
user=self.request.user
serializer.save(user=user)
class FooBarUpdateDestroyView(LoginRequiredMixin, UpdateDestroyAPIView):
queryset=FooBar.objects.all()
serializer_class = FooBarDetailsSerializer
permission_classes = [IsOwner]
Therefore, is there a way to check a user is looged in ViewSets or am I forced to use a JWT authentication system, save the tokens client-side (is that even safe?), and from the front-end make sure that for every request the user provides those in the headers?
Any help on how to implement this in ViewSets would be appreciated.