Используйте React fetch, чтобы вызвать Dango REST и получить ответ 403 - PullRequest
0 голосов
/ 05 июня 2019

Я размещаю приложение React (http://localhost:3000/) и хочу аутентифицировать пользователя из приложения Django REST (http://127.0.0.1:8000/) с помощью вызова fetch . Я использую django-cors-headers для решения проблемы CORS, но все равно появляется ошибка 403 Forbidden (CSRF cookie not set.): /api-auth/login/ /

Мой пользователь является прямым подклассом django.contrib.auth.models.AbstractUser, и я использую rest_framework.urls LoginView для входа в систему пользователяв. Если я вызываю это из встроенного шаблона Django (http://127.0.0.1:8000/api-auth/login/), я могу успешно войти в систему, но когда я отправляю POST из приложения React, используя fetch , я получаю ошибку 403.

Я использую django-core-headers для вызова CORS, но не похоже, чтобы он отправлял Cookies обратно с ответом.

Я пытался POSTing на http://127.0.0.1:8000/api-auth/login/ используя Почтальон, который также получает ошибку 403.

urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('', include('users.urls')),
    path('admin/', admin.site.urls),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

Часть settings.py:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'rest_framework',
    'corsheaders',

    'users',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    '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',
]

AUTH_USER_MODEL = 'users.User'
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    )
}

CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
SESSION_COOKIE_SAMESITE = None

CSRF_TRUSTED_ORIGINS = [
    'localhost:3000',
    '127.0.0.1:3000',
]

Я звоню APIиспользуя fetch .

handleLogin (e) {
    e.preventDefault();
    fetch('http://127.0.0.1:8000/api-auth/login/', {
      method: 'POST',
      credentials: 'include',
      headers: {
        'X-CSRFToken': Cookies.get('csrftoken'),
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(this.state)
    })
      .then(response => {
        console.log(response.body)
        return response
      })
    }

Пользователь может быть правильно аутентифицирован при вызове DRF с http://127.0.0.1:8000/, поэтому я уверен, что приложение DRFработает как положено.Может ли кто-нибудь помочь мне решить проблему связи между приложением React и DRF?

1 Ответ

1 голос
/ 06 июня 2019

Ваше приложение реагирования должно запросить csrftoken с сервера, используя подходящую конечную точку, и сохранить этот файл cookie.

Например:

# Django view.py
def get_csrf(request):
    return HttpResponse("{0}".format(csrf.get_token(request)), content_type="text/plain")

# Django urls.py
url(r'^api/get_csrf/?$', get_csrf, name="get_csrf"),

Код JS:

$.get( "api/get_csrf/", function(data) {
  Cookies.set('csrftoken', data);
});
...