django - 使用 Django 的 CSRF,使用 Axios 的 React+Redux

标签 django reactjs redux django-csrf axios

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

我可以在没有用户登录的情况下使用 CSRF token 对 Django 进行 POST 调用吗?我可以在不使用 jQuery 的情况下执行此操作吗?我在这里超出了我的深度,并且肯定会混淆一些概念。

对于 JavaScript 方面,我发现了这个 redux-csrf包裹。我不确定如何使用 Axios 将它与我的 POST 操作结合起来:

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 方面,我读过 this documentation在 CSRF 上,和 this关于一般使用基于类的 View 。

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

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装饰器只是暂时不必担心这个,但这似乎不是它的工作原理。

我已将 {% csrf_token %} 添加到我的模板中。

这是我的 getCookie 方法(从 Django 文档中窃取):

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

I've read我需要更改 Axios CSRF 信息:

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

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

我应该把实际的 token 放在哪里,我通过调用 getCookie('csrftoken') 获得的值?

最佳答案

这个问答是从 2016 年开始的,不出所料,我相信情况已经发生了变化。答案继续收到赞成票,因此我将添加其他答案的新信息,但也保留原始答案。

在评论中让我知道哪种解决方案适合您。

选项 1. 设置默认 header

在导入 Axios 的文件中,设置默认 header :

import axios from 'axios';
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.xsrfCookieName = "csrftoken";

方案2.手动添加到axios调用

假设您已将 token 的值存储在名为 csrfToken 的变量中。在 axios 调用中设置 header :

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

选项 3. 在调用中设置 xsrfHeaderName:

添加这个:

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

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

CSRF_COOKIE_NAME = "XSRF-TOKEN"

编辑(2017 年 6 月 10 日):用户@yestema 说它与 Safari 的工作方式略有不同 [2]

编辑(2019 年 4 月 17 日):用户@GregHolst 说上面的 Safari 解决方案对他不起作用。相反,他在 MacOS Mojave 上对 Safari 12.1 使用了上述解决方案 #3。 (来自评论)

编辑(2019 年 2 月 17 日):您可能还需要设置 [3] :

axios.defaults.withCredentials = true

我尝试过但没有用的东西:1

关于django - 使用 Django 的 CSRF,使用 Axios 的 React+Redux,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39254562/

相关文章:

javascript - 序列化 Django 模型

javascript - 在 Django 中处理模式窗口

javascript - 使用 React-Laravel 相对于普通 React 和 Laravel 的优缺点

javascript - 如果调用方法后不小心没有使用 '()'怎么办

javascript - 未处理的拒绝(类型错误): dispatch is not a function getting this error in action creator

javascript - React Hooks 和 Redux - 从 action creator 获取值(value)时遇到困难

javascript - 组件无法跟上 redux 状态

python - 在 Django 站点中将 HTML 渲染为 PDF

python - 有条件地显示来自单个 TastyPie 资源的全部或部分字段

javascript - 如何在firestore中存储二叉树节点