Search code examples
pythondjango-rest-frameworkdjango-serializerdjango-authenticationauth-token

permission classes IsAuthenticated not working in DRF


I've used token authentication, and it's working fine i.e. it is authenticating a user and then the user is logged in. But in my views I've set permission classes to IsAuthenticated for one of the views, and it is not allowing to the user even if he is an authenticated user. Below is the screenshot where it says i'm logged in ([email protected]) :

enter image description here

and the very next tab to this, it says "Authentication credentials were not provided.":

enter image description here

Can someone tell what's wrong? ok, I'm providing details: these are my settings:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated', )
}

This is how I authenticated:

class UserLoginAPIView(APIView):

    permission_classes = [AllowAny]
    serializer_class = UserLoginSerializer

    def post(self, request, *args, **kwargs):
        data = request.data
        serializer = UserLoginSerializer(data=data)
        if serializer.is_valid(raise_exception=True):
            # new_data = serializer.data
            if serializer.data:
                user = authenticate(username=request.data['username'], password=request.data['password'])
                login(request, user)
                print("IsAuthenticated", user.is_authenticated)
            token, _ = Token.objects.get_or_create(user=user)
            return Response({'token': token.key},
                            status=HTTP_200_OK)

Another View where I put restrictions:

class BoardCreateAPIView(CreateAPIView):
    queryset = Boards.objects.all()
    serializer_class = BoardCreateSerializer
    permission_classes = (IsAuthenticated,)

Solution

  • Just as @Reza hinted, you're missing the point of token authentication. You're trying to use the basic authentication flow instead. The flow is like this:

    1. Client requests a token from the server using login and password
    2. Server verifies that your credentials are correct, creates a token and returns it to the client
    3. In subsequent requests, client adds the token to the Auth header like this:

      Authorization: Token <the_client_token>

    So what you should do in your login view is verify the user credentials and create a token. you shouldn't try to perform the authentication yourself. You can rename the view to obtain_token so as not to confuse its function.

    Check the article @Reza linked for more info.