Django REST framework gives me csrf token missing when i am logged in for POST requests

i am making an API with django rest framework and django 5.2 when i send a POST request, if i be logged in it gives me an CSRF token missing error. but if i be logged out it gives me response with no error. here are my views for handling user creation and authentication:

@api_view(['POST'])
def signup_view(request):
    if not request.user.is_authenticated:
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()

            return Response(serializer.data)
    
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    return Response({"detail": "The user is already logged in."}, status=status.HTTP_403_FORBIDDEN)

@api_view(['POST'])
def login_view(request):
    if not request.user.is_authenticated:
        
        user = authenticate(**request.data)
        print(request.POST)
        if not user:
            return Response({"detail": "User authentication failed."}, status=status.HTTP_400_BAD_REQUEST)
        
        login(request, user)
        return Response({"detail": "Login was succesful."})
    
    return Response({"detail": "The user is already logged in."}, status=status.HTTP_403_FORBIDDEN)

and here are my views for handling get and post method for the model:

class NoteListView(APIView):
    def get(self, request):
        notes = Note.objects.filter(author=request.user)
        serializer = NoteSerializer(notes, many=True)
        data = []

        for note in serializer.data:
            data.append({'title': note['title']})

        return Response(data)
        
    def post(self, request):
        serializer = NoteSerializer(data=request.data)
        serializer.initial_data['author'] = request.user
        print("1")
        
        if serializer.is_valid():
            print("2")
            serializer.save()
            print("3")
            return Response(serializer.data)
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

now i want to know what i have to do for fixing the csrf missing error in this situation.

I developed a project like you and added the following lines to settings.py to fix this problem.

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'my_app.custom_authentication.CustomJWTAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
}

Then I defined a class called CustomJWTAuthentication. In this class, you need to define a method called authenticate, and its return values ​​will be user and token.

class CustomJWTAuthentication(JWTAuthentication):
    def authenticate(self, request):
        auth = get_authorization_header(request).split()

        if not auth or auth[0].lower() != b'bearer':
            return None
        .
        .
        .
        .
        return (user, token)

Then you need to add the following lines to your views:

class MyView(APIView):
    authentication_classes = [CustomJWTAuthentication]
    permission_classes = [IsAuthenticated]

Once you do these, auth controls are transferred to you and your CSRF token missing error will gone away.

I also recommend to change your middleware list as below:

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware', # <------------ add this
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
Вернуться на верх