如何使用 Axios 将 CSRF Cookie 从 React 发送到 Django Rest Framework

问题描述 投票:0回答:2

我想使用 AxiosReact 应用程序向 Django Rest Framework 后端发出 POST 请求。我已经设法从后端获得了一个CSRF令牌,但我无法将其与我的请求一起发送,所以我总是收到一个

Forbidden (CSRF cookie not set.)
错误:

这是我的 React 应用程序的代码:

handleClick() {
    const axios = require('axios');
    var csrfCookie = Cookies.get('XSRF-TOKEN');
    console.log(csrfCookie)
    axios.post('http://127.0.0.1:8000/es/api-auth/login/',
      {
        next: '/',
        username: '[email protected]',
        password: 'Cancun10!',
      },
      {
        headers: {
          'x-xsrf-token': csrfCookie,  // <------- Is this the right way to send the cookie?
        },
        withCredentials = true,
      }
    )
    .then(function (response) {
      console.log(response);
    })
    .catch(function (error) {
      console.log(error);
    })
  }

这是我的

settings.py
CSRF 配置:

CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_HEADERS = (
    'xsrfheadername',
    'xsrfcookiename',
    'content-type',
    'XSRF-TOKEN',
)

CORS_ORIGIN_WHITELIST = serverconfig.CORS_ORIGIN_WHITELIST
CSRF_TRUSTED_ORIGINS = serverconfig.CSRF_TRUSTED_ORIGINS
CSRF_COOKIE_NAME = "XSRF-TOKEN"
reactjs django-rest-framework axios csrf django-csrf
2个回答
6
投票

Django 默认使用

X-CSRFTOKEN
作为 csrf 标头,请参阅 here。您在 Django 设置中使用的选项
CSRF_COOKIE_NAME
仅更改 cookie 名称,默认情况下为
csrftoken
,请参阅 here

要解决您的问题,请在 axios 调用中使用此标头:

headers: { 'X-CSRFTOKEN': csrfCookie }

使用以下内容:

axios.post('http://127.0.0.1:8000/es/api-auth/login/',
    {
        next: '/',
        username: '[email protected]',
        password: 'Cancun10!',
    },
    {
        headers: {
             'X-CSRFTOKEN': csrfCookie,
         },
    },
)

此外,在 Django 设置中从

XSRF-TOKEN
中删除
CORS_ALLOW_HEADERS
,然后添加
X-CSRFTOKEN
。如果您不想删除
XSRF-TOKEN
,您可以使用以下文档将
X-CSRFTOKEN
安全地添加到
CORS_ALLOW_HEADERS
,文档此处

# settings.py

from corsheaders.defaults import default_headers

CORS_ALLOW_HEADERS = list(default_headers) + [
    'X-CSRFTOKEN',
]

5
投票

另外,如果你创建一个Axios实例会更容易

const instance = axios.create({
  baseURL: API_URL,
  withCredentials: true,
  xsrfHeaderName: 'X-CSRFToken',
  xsrfCookieName: 'csrftoken',
})

并确保

xsrfCookieName
CSRF_COOKIE_NAME
具有相同的名称。请注意,如果
CSRF_COOKIE_HTTPONLY
设置为 True,客户端 JavaScript 将无法访问 CSRF cookie:

# settings.py

CSRF_COOKIE_NAME = "csrftoken"
CSRF_COOKIE_HTTPONLY = False

CORS_EXPOSE_HEADERS = ["Content-Type", "X-CSRFToken"]
CORS_ALLOW_CREDENTIALS = True
© www.soinside.com 2019 - 2024. All rights reserved.