Почему Django REST Framework выдает ошибку 403 Forbidden для запросов без GET, отправленных с каждого компьютера, кроме моего? - PullRequest
0 голосов
/ 05 августа 2020

В настоящее время я разрабатываю веб-приложение с Django REST Framework API. Он отлично работает на компьютере, на котором я разработал веб-приложение (оно размещено в сети, а не локально, поэтому мне это кажется странным), но затем, когда я пытаюсь войти на сайт с любого другого компьютера, все запросы GET работают отлично. (аутентификация пользователя также работает правильно), но любые запросы POST, DELETE или PUT, сделанные интерфейсом к API, получают ошибку 403. Запрещено.

Я использую интерфейс React и использую выборку API для выполнения запросов к бэкэнду.

Вот важные части моего файла settings.py (приложение развертывается с использованием heroku):

import django_heroku

DEBUG = False

ALLOWED_HOSTS = ['somehostdomain']

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication'
    )
}

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    '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',
]

CORS_ALLOW_CREDENTIALS = True

CORS_ORIGIN_WHITELIST = [
    'http://somedomain'
]

django_heroku.settings(locals())

Каждый запрос внешнего интерфейса выглядит примерно так :

    someRequest(parameter) {
        let csrftoken = this.getCookie('csrftoken');

        fetch('https://somedomain/api/some-request/', {
            method: 'POST',
            credentials: 'include',
            headers: {
                'Content-type': 'application/json',
                'X-CSRFToken': csrftoken
            },
            body: JSON.stringify({
                "parameter": parameter
            })
        })
    }

где функция getCook ie просто создает csrftoken (эта часть не является исходным кодом, она широко используется):

    getCookie(name) {
        let cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            const cookies = document.cookie.split(';');
            for (let i = 0; i < cookies.length; i++) {
                const cookie = cookies[i].trim();
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    } 

Я думаю, что ошибка либо имеет какое-то отношение к CORS или Django Разрешения REST Framework , но ничего из того, что я пробовал до сих пор, не помогло.

Я пробовал вручную поставить allo w any in rest framework permissions (в любом случае это поведение по умолчанию, поэтому оно не сработало):

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny',
    ]
}

Кто-нибудь знает, в чем может быть проблема?

1 Ответ

0 голосов
/ 05 августа 2020

Убедитесь, что ваш csrftoken установлен правильно и передан вместе с запросом. Похоже, что ваш токен CSRF не работает. DRF потребует наличия токена CSRF для методов POST / PUT / DELETE после входа в систему.

...