简体   繁体   English

如何使用 Axios 将 CSRF Coo​​kie 从 React 发送到 Django Rest Framework

[英]How to send CSRF Cookie from React to Django Rest Framework with Axios

I want to make a POST request from a React app using Axios to a Django Rest Framework backend.我想从使用AxiosReact应用程序向Django Rest Framework后端发出POST请求。 I have managed to get a CSRF Token from the backend but I can't manage to send it with my request, so I always get a Forbidden (CSRF cookie not set.) error:我设法从后端获取了CSRF 令牌,但我无法通过我的请求发送它,所以我总是收到Forbidden (CSRF cookie not set.)错误:

This is the code of my React app:这是我的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: 'admin@admin.com',
        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);
    })
  }

And this is my settings.py CSRF configuration:这是我的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"

Django uses X-CSRFTOKEN as the csrf header by default, see here . Django默认使用X-CSRFTOKEN作为csrf标头,请参见此处 The option CSRF_COOKIE_NAME you use in your Django settings only changes the cookie name, which by default is csrftoken , see here . 选项CSRF_COOKIE_NAME你在你的Django设置使用只更改cookie的名称,而默认情况下csrftoken ,看这里

To solve your issue, use this header in your axios call: headers: { 'X-CSRFTOKEN': csrfCookie } . 要解决您的问题,请在axios调用中使用以下标头: headers: { 'X-CSRFTOKEN': csrfCookie }

Use the following: 使用以下内容:

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

Also, remove XSRF-TOKEN from CORS_ALLOW_HEADERS in your Django settings, and add X-CSRFTOKEN to it instead. 另外,从Django设置中的CORS_ALLOW_HEADERS中删除XSRF-TOKEN ,然后向其中添加X-CSRFTOKEN If you don't feel like removing XSRF-TOKEN , you can safely add X-CSRFTOKEN to CORS_ALLOW_HEADERS with the following, documentation here 如果你不喜欢删除XSRF-TOKEN ,你可以安全地添加X-CSRFTOKENCORS_ALLOW_HEADERS与以下,文档在这里

# settings.py

from corsheaders.defaults import default_headers

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

Also, it's will be easier if you create an Axios instance此外,如果您创建一个 Axios 实例会更容易

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

And make sure xsrfCookieName and CSRF_COOKIE_NAME have the same name.并确保xsrfCookieNameCSRF_COOKIE_NAME具有相同的名称。 Note that if CSRF_COOKIE_HTTPONLY set to True, client-side JavaScript will not be able to access the CSRF cookie:请注意,如果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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM