CSRF与Django,React + Redux使用Axios [英] CSRF with Django, React+Redux using Axios

查看:454
本文介绍了CSRF与Django,React + Redux使用Axios的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个教育项目,而不是生产。我不打算将用户登录作为其中的一部分。

This is an educational project, not for production. I wasn't intending to have user logins as part of this.

可以使用CSRF令牌对Django进行POST调用,而无需用户登录?我可以不使用jQuery吗?我在这里不在我的深度,肯定混淆了一些概念。

Can I make POST calls to Django with a CSRF token without having user logins? Can I do this without using jQuery? I'm out of my depth here, and surely conflating some concepts.

对于JavaScript端,我发现这个 redux-csrf 包。我不知道如何将它与我的 POST 动作结合使用Axios:

For the JavaScript side, I found this redux-csrf package. I'm not sure how to combine it with my POST action using Axios:

export const addJob = (title, hourly, tax) => {
  console.log("Trying to addJob: ", title, hourly, tax)
  return (dispatch) => {
    dispatch(requestData("addJob"));
    return axios({
      method: 'post',
      url: "/api/jobs",
      data: {
        "title": title,
        "hourly_rate": hourly,
        "tax_rate": tax
      },
      responseType: 'json'
    })
      .then((response) => {
        dispatch(receiveData(response.data, "addJob"));
      })
      .catch((response) => {
        dispatch(receiveError(response.data, "addJob"));
      })
  }
};






在Django端, CSRF上的一个href =https://docs.djangoproject.com/en/1.10/ref/csrf/ =noreferrer>本文档,以及这个

这是我到目前为止的观点:

Here is my view so far:

class JobsHandler(View):

    def get(self, request):
        with open('./data/jobs.json', 'r') as f:
            jobs = json.loads(f.read())

        return HttpResponse(json.dumps(jobs))

    def post(self, request):
        with open('./data/jobs.json', 'r') as f:
            jobs = json.loads(f.read())

        new_job = request.to_dict()
        id = new_job['title']
        jobs[id] = new_job

        with open('./data/jobs.json', 'w') as f:
            f.write(json.dumps(jobs, indent=4, separators=(',', ': ')))

        return HttpResponse(json.dumps(jobs[id]))

我尝试使用 csrf_exempt 装饰器只是没有现在担心这一点,但这似乎不是如何工作的。

I tried using the csrf_exempt decorator just to not have to worry about this for now, but that doesn't seem to be how that works.

我添加了 {%csrf_token%} / code>到我的模板。

I've added {% csrf_token %} to my template.

这是我的 getCookie 方法(从Django文档偷走):

This is my getCookie method (stolen from Django docs):

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var 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;
}

我已阅读,我需要更改Axios CSRF信息:

I've read that I need to change the Axios CSRF info:

var axios = require("axios");
var axiosDefaults = require("axios/lib/defaults");

axiosDefaults.xsrfCookieName = "csrftoken"
axiosDefaults.xsrfHeaderName = "X-CSRFToken"

我在哪里贴实际的令牌,我从调用 getCookie('csrftoken')获得的值

Where do I stick the actual token, the value I get from calling getCookie('csrftoken')?

推荐答案

有三种方法。您可以手动将令牌包含在每个axios调用的头文件中,您可以在每个调用中设置axios的 xsrfHeaderName ,或者设置默认的 xsrfHeaderName

There are three ways. You can manually include the token in the header of each axios call, you can set axios's xsrfHeaderName in each call, or you set a default xsrfHeaderName.

假设您已经获得了名为 csrfToken 的变量的值。设置您的轴心调用中的标题:

Let's say you've got the value of the token stored in a variable called csrfToken. Set the headers in your axios call:

// ...
method: 'post',
url: '/api/data',
data: {...},
headers: {"X-CSRFToken": csrfToken},
// ...



2。在电话中设置 xsrfHeaderName



添加:

2. Setting xsrfHeaderName in the call:

Add this:

// ...
method: 'post',
url: '/api/data',
data: {...},
xsrfHeaderName: "X-CSRFToken",
// ...

然后在您的 settings.py 文件中,添加以下行:

Then in your settings.py file, add this line:

CSRF_COOKIE_NAME = "XSRF-TOKEN"



3。设置默认标题 [1]



不必在每个通话中定义标题,您可以为axios设置默认标题。

3. Setting default headers[1]

Rather than defining the header in each call, you can set default headers for axios.

在您导入座席电话的文件中,添加以下导入:

In the file where you're importing axios to make the call, add this below your imports:

axios.defaults.xsrfHeaderName = "X-CSRFToken";

然后在您的 settings.py 文件中,添加以下行:

Then in your settings.py file, add this line:

CSRF_COOKIE_NAME = "XSRF-TOKEN"

[1] 从Dave Merwin的评论< a>

[1] From Dave Merwin's comment

混乱:

首先,从 Django docs James Evans 参考

First, the whole passage from the Django docs that James Evans referenced:


...在每个XMLHttpRequest上,将自定义X-CSRFToken头设置为CSRF令牌的
值。这通常更容易,因为许多JavaScript
框架提供了允许在每个
请求上设置头文件的钩子。

...on each XMLHttpRequest, set a custom X-CSRFToken header to the value of the CSRF token. This is often easier, because many JavaScript frameworks provide hooks that allow headers to be set on every request.

作为第一步,你必须获得CSRF令牌本身。令牌的推荐
来源是csrftoken cookie,如果
已启用了您对上述视图的CSRF保护,则会设置此cookie。

As a first step, you must get the CSRF token itself. The recommended source for the token is the csrftoken cookie, which will be set if you’ve enabled CSRF protection for your views as outlined above.

注意

默认情况下,CSRF令牌cookie名为csrftoken,但您可以通过CSRF_COOKIE_NAME设置来控制cookie名称

The CSRF token cookie is named csrftoken by default, but you can control the cookie name via the CSRF_COOKIE_NAME setting.

默认情况下,CSRF头名称为HTTP_X_CSRFTOKEN,但您可以使用CSRF_HEADER_NAME设置
自定义。

The CSRF header name is HTTP_X_CSRFTOKEN by default, but you can customize it using the CSRF_HEADER_NAME setting.






Axios文件



这是从 Axios文档。它表示您设置包含 csrftoken 的cookie的名称,以及此处的标题名称:


Axios Docs

This is from the Axios docs. It indicates that you set the name of the cookie which contains the csrftoken, and the name of the header here:

  // `xsrfCookieName` is the name of the cookie to use as a value for xsrf token
  xsrfCookieName: 'XSRF-TOKEN', // default

  // `xsrfHeaderName` is the name of the http header that carries the xsrf token value
  xsrfHeaderName: 'X-XSRF-TOKEN', // default






条款



如我的问题所示,使用 document.cookie 访问Cookie。我唯一的cookie是我放在Django模板中的CSRF令牌。以下是一个例子:


Terms

As indicated in my question, you access cookies with document.cookie. The only cookie I have is the CSRF token I put in the Django template. Here is an example:

csrftoken = 5knNceCUi9nL669hGGsvCi93XfqNhwTwM9Pev7bLYBOMXGbHVrjitlkKi44CtpFU

这些文档中有一些概念被引起了混乱:

There are a few concepts being thrown around in those docs that get confusing:


  • 包含CSRF令牌的cookie的名称。在Django中,这是默认的 csrftoken ,它位于cookie等号的左侧。

  • 实际的令牌。这是cookie中等号的右侧的一切。

  • 带有令牌值的http标头。

  • The name of the cookie that contains the CSRF token. In Django this is by default csrftoken, which is on the left side of the equals sign in the cookie.
  • The actual token. This is everything on the right side of the equals sign in the cookie.
  • The http header that carries the token value.

我尝试的事情没有起作用: 1 2

Things I tried that didn't work: 1, 2

这篇关于CSRF与Django,React + Redux使用Axios的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆