I have used simplejwt in my code and I also have added django-cors-headers to my project to allow frontend development. the problem is that I have 2 APIs that need authentication to allow users to work with them and I can not send a request to these two APIs on the front end and I get the following error:

Access to fetch at 'http://localhost:8000/api/user/myapi' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field x-auth-token is not allowed by Access-Coontrol-Allow-Headers in preflight response

Here are the important parts of my settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'rest_framework.authtoken',
    'rest_framework_simplejwt',
    'corsheaders',
    ...
]

MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware',
]

ALLOWED_HOSTS=['*']
CORS_ORIGIN_ALLOW_ALL = True

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),  
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10,
}

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(days=10),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=10),
    'ROTATE_REFRESH_TOKENS': True,
    'BLACKLIST_AFTER_ROTATION': False,
    'ALGORITHM': 'HS256',
    'SIGNING_KEY': SECRET_KEY,
    'VERIFYING_KEY': None,
    'AUTH_HEADER_TYPES': ('JWT',),
    'USER_ID_FIELD': 'userID',
    'USER_ID_CLAIM': 'user_id',
    'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
    'TOKEN_TYPE_CLAIM': 'token_type',
}

and here are my views.py and serializers.py

# Serializers.py
class myAPISerializer(serializers.ModelSerializer):
    class Meta:
        model = someModel
        fields = ('user', 'someField',)
        read_only_fields = ('user',)

    def create(self, validated_data):
        ... #Some changes
        return super().create(validated_data)

# Views.py
class PaymentView(generics.CreateAPIView):
    serializer_class = PaymentSerializer

    def get_queryset(self):
        return Payment.objects.all()

Solution 1:

According django-cors-headers documentation:

CorsMiddleware should be placed as high as possible, especially before any middleware that can generate responses such as Django’s CommonMiddleware or Whitenoise’s WhiteNoiseMiddleware. If it is not before, it will not be able to add the CORS headers to these responses.

So just add it at the top of your list, like this:

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    ...,
]