Getting error for django and react native code Forbidden (CSRF token missing.):

  Kiến thức lập trình

I am working on a Django backend to handle some data manipulation, specifically appending and deleting data. My code works perfectly when tested with Postman, but I encounter a 403 Forbidden error when trying to access the /bookings/remove/ endpoint from my React Native frontend.

Here’s the error message I receive:
Forbidden (CSRF token missing.): /bookings/remove/ "POST /bookings/remove/?booking_id=148/ HTTP/1.1" 403

Interestingly, all other endpoints are working fine without any CSRF-related issues. It’s only this specific endpoint that is causing problems.

Django Backend

i have my settings for cors as follows:


INSTALLED_APPS = [
    'corsheaders',
    "all other apps"
]

SESSION_COOKIE_SECURE = False
SESSION_COOKIE_SAMESITE = None
SESSION_COOKIE_AGE = 1209600

CORS_ALLOW_ALL_ORIGINS = True


MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',  
    'django.middleware.security.SecurityMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10,
}

and my endpoint for which i am getting error is

@api_view(["POST"])
@permission_classes([IsAuthenticated])
@csrf_exempt
def cancel_the_booking(request, booking_id):
    try:
        if not booking_id:
            return Response({"error": "Booking ID is required"}, status=status.HTTP_400_BAD_REQUEST)

        booking = Booking.objects.get(booking_id=booking_id)
        if booking.host_id != request.user.id:
            return Response({"error": "You are not authorized to cancel this booking", "host": request.user.id}, status=status.HTTP_403_FORBIDDEN)

        for date_price in booking.dates_price.all():
            AdSpaceDates.objects.create(
                ad_space=booking.space_id,
                available_from=date_price.available_from,
                available_to=date_price.available_to,
                price=date_price.price
            )

        booking.delete()

        return Response({"success": "Booking cancelled and dates are now available again"}, status=status.HTTP_200_OK)
    except Booking.DoesNotExist:
        return Response({"error": "Booking does not exist"}, status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

my urls.py for Booking app

    path('remove/<int:booking_id>/', cancel_the_booking , name="cancel_the_booking")

and my project urls.py is

    path("bookings/", include("Bookings.urls")),

to retrive the csrf

@api_view(["GET"])
@ensure_csrf_cookie
def get_csrf_token(request):
    csrf_token = get_token(request)
    return JsonResponse({'csrfToken': csrf_token})


path('api/get-csrf-token/', get_csrf_token, name='get_csrf_token'),

React Native code

  const getCsrfToken = async () => {
    try {
      const response = await Api.get('/api/get-csrf-token/');
      return response.data.csrfToken;
    } catch (error) {
      console.error('Error fetching CSRF token', error);
      return null;
    }
  };

  const handleConfirmButton = (booking) => {
    Alert.alert(
      'Cancel Booking',
      'Are you sure you want to cancel this booking?',
      [
        {
          text: 'No',
          onPress: () => console.log('Cancel Pressed'),
          style: 'cancel',
        },
        {
          text: 'Yes',
          onPress: () => handleBookingCancellation(booking),
        },
      ],
      { cancelable: false }
    );
  };

const handleBookingCancellation = async (booking) => {
  try {
    const csrfToken = await getCsrfToken();
    if (!csrfToken) {
      Alert.alert('Error', 'Failed to fetch CSRF token');
      return;
    }

    const response = await axios.post(`http://127.0.0.1:8000/bookings/remove/?booking_id=${booking.booking_id}/`, {
      headers: {
        'Authorization': `Bearer ${await SecureStore.getItemAsync('access')}`,
        'X-CSRFToken': csrfToken 
      },
    });

    Alert.alert("Booking Cancelled", `Booking ID: ${booking.booking_id}`);
    console.log(response);
  } catch (error) {
    console.error('Error cancelling booking', error);
    Alert.alert('Error', 'There was an error cancelling the booking');
  }
};


        <TouchableOpacity style={styles.confirmButton } onPress={() => handleConfirmButton(item)} >
            <Text style={styles.viewAllText}>Cancel Booking</Text>
            <AntDesign name="delete" size={24} color="white" style={styles.icon} />
        </TouchableOpacity>

I have tried multiple approaches to resolve the 403 Forbidden (CSRF token missing) error specifically for the /bookings/remove/ endpoint:

  • Fetching the CSRF Token:

Implemented a CSRF token fetch from the backend using a dedicated endpoint (/api/get-csrf-token/).
The token fetch works correctly and returns a valid CSRF token.

  • Sending the CSRF Token in Requests:

Modified the fetch request in React Native to include the CSRF token in the headers.
Expected the backend to accept the request and process the booking cancellation.

  • Adjusting Django Settings:

Ensured CSRF_TRUSTED_ORIGINS and CORS_ALLOWED_ORIGINS include the frontend URLs.
Enabled CORS_ALLOW_ALL_ORIGINS.

  • Changing HTTP Method and Headers:

Tried using both POST and DELETE methods.
Included necessary headers (Authorization, Content-Type, and X-CSRFToken).

Despite these efforts, the request to /bookings/remove/ consistently results in a 403 Forbidden (CSRF token missing) error. Other endpoints are functioning correctly without this issue, which is confusing.

I was expecting the request to succeed, cancel the booking, and return a confirmation response, but it fails at the CSRF validation stage.

I expected that after correctly fetching and including the CSRF token in the request headers, the backend would validate the token and allow the booking cancellation request to proceed without returning a 403 Forbidden error.

while everything working fine with postman.

LEAVE A COMMENT