当前位置: 首页 > 面试题库 >

带有Django的CSRF,使用Axios的React + Redux

麹培
2023-03-14
问题内容

这是一个教育项目,不用于生产。我本来不想让用户登录。

我可以在没有用户登录的情况下使用CSRF令牌对Django进行POST调用吗?我可以不使用jQuery来做到这一点吗?我在这里不了解我的观点,并且肯定会混淆一些概念。

在JavaScript方面,我找到了这个redux-csrf软件包。我不确定如何将其与POST使用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的文档,并且该文档通常与基于类的视图一起使用。

到目前为止,这是我的看法:

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

我读到我需要更改Axios CSRF信息:

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

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

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


问题答案:

有三种方法。你可以在每个axios调用的标题中手动添加令牌,可以xsrfHeaderName在每个调用中设置axios的令牌,或者设置default xsrfHeaderName

1.手动添加
假设你已将令牌的值存储在名为的变量中csrfToken。在axios调用中设置标题:

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

  1. xsrfHeaderName在通话中设置:
  2. 添加此:
// ...
method: 'post',
url: '/api/data',
data: {...},
xsrfHeaderName: "X-CSRFToken",
// ...

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

CSRF_COOKIE_NAME = "XSRF-TOKEN"

3.设置默认标题[1]
你可以为axios设置默认标题,而不是在每个调用中定义标题。

在导入axios进行呼叫的文件中,将其添加到你的导入下方:

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

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

CSRF_COOKIE_NAME = "XSRF-TOKEN"
axios.defaults.withCredentials = true

问题:下一节对任何人有用吗?我想知道是否可以仅通过包含解决方案来改善此答案。如果你有意见,请告诉我。

混乱:

Django文档

首先,James Evans 引用的Django文档的整个段落:

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

第一步,你必须获取CSRF令牌本身。令牌的推荐来源是csrftoken cookie,如果你如上所述为视图启用了CSRF保护,则将设置该cookie。

注意

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

默认情况下,CSRF标头名称为HTTP_X_CSRFTOKEN,但你可以使用CSRF_HEADER_NAME设置对其进行自定义。

Axios文件

这是来自Axios文档。它表示你csrftoken在此处设置了包含的Cookie 的名称以及标头的名称:

  // `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


 类似资料:
  • 我想从React获取数据到Django后端,并用'request'请求url中的参数。收到获取(“,无)”[或备选方案?]。最好的情况是针对多个参数或体内的解决方案。每个教程都只显示fetch to模型,但我为request或create()找到的所有引用都是视图中的参数。py(在视图中使用值执行其他操作)不起作用。 我想从url中刮取'name'(在接下来的步骤中,我也需要'params'从bo

  • 问题内容: 我想在Rails 4应用程序中使用material-ui组件库。我目前正在使用react-rails gem将.jsx编译添加到资产管道。我已经在gemfile中通过rails-assets添加了material-ui,如下所示: 我需要在application.js文件中添加该库,如下所示: 但是,我不断收到错误消息“找不到文件’material-ui”。如何将我的Rails应用程序

  • 问题内容: 我可以通过我的AJAX帖子向遵循Django CSRF保护机制的人员提供帮助。我按照这里的指示进行: http://docs.djangoproject.com/en/dev/ref/contrib/csrf/ 我已经精确地复制了他们在该页面上拥有的AJAX示例代码: http://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

  • 问题内容: 我正在尝试在我的项目中实现csrf保护,但无法使其与jQuery Ajax一起使用。(不过,它适用于普通的帖子请求) 如果在发送表单之前使用chrome开发工具篡改令牌,则仍会看到“正在处理数据”文本,而不是错误。 app.js send.jade test.js 问题答案: 在有效负载消息中发送CSRF令牌: 为了简化您的工作,我认为您可以创建一个Jquery插件来执行此操作,如下所

  • 问题内容: 我想使用出色的create-react- app工具来启动新的react项目,但是我需要使用php服务应用,以允许我获取一些动态数据和配置,并在启动之前对其进行反馈。 我如何将create-react-app配置为服务器php? php有自己的内置服务器,所以也许我们可以用它来启动index.php 有没有办法让webpack启动php内置服务器,并且仍然具有react-create-

  • 示例: 爱丽丝通过浏览器登录到“https://example.com”(使用cookie)。我想,她使用的是现代浏览器。 爱丽丝访问“https://evil.com”,而evil.com的客户端代码对“https://example.com”执行某种请求(经典CSRF场景)。 所以: null null