【问题标题】:Use React fetch to call Dango REST getting a 403 response使用 React fetch 调用 Dango REST 得到 403 响应
【发布时间】:2020-01-07 13:24:27
【问题描述】:

我正在托管一个 React 应用程序 (http://localhost:3000/) 并希望使用 fetch 调用从 Django REST 应用程序 (http://127.0.0.1:8000/) 对用户进行身份验证。我正在使用 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/) 调用它,我可以成功登录,但是当我使用 fetch 从 React 应用发布 403 错误。

我使用django-core-headers 进行 CORS 挑战,但它似乎没有将 Cookie 与响应一起发回。

我尝试使用 Postman 发布到 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',
]

我正在使用 fetch 调用 API。

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
      })
    }

在从http://127.0.0.1:8000/ 调用 DRF 时,用户可以正确地进行身份验证,因此我确信 DRF 应用程序按预期工作。有人可以帮我解决 React 应用程序和 DRF 之间的连接问题吗?

【问题讨论】:

  • 您已启用 csrf,端点调用可能需要 CSRF 令牌。使用中间件:django.middleware.csrf.CsrfViewMiddleware。更多信息:docs.djangoproject.com/en/2.2/ref/csrf
  • @josemlp 标题的'X-CSRFToken': Cookies.get('csrftoken') 部分没有提供吗?

标签: reactjs django-rest-framework fetch


【解决方案1】:

您的 React 应用程序必须使用合适的端点从服务器请求 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);
});

【讨论】:

    猜你喜欢
    • 2022-08-05
    • 2016-08-07
    • 2023-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-03
    • 2019-10-03
    • 2016-12-14
    相关资源
    最近更新 更多