这是一个教育项目,不是为了生产。我不打算让用户登录作为其中的一部分。
我可以在没有用户登录的情况下使用 CSRF 令牌对 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 方面,我已经阅读 了有关 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')
获得的值?
原文由 Reed Dunkle 发布,翻译遵循 CC BY-SA 4.0 许可协议
这个问答是从 2016 年开始的,不出所料,我相信事情已经发生了变化。答案继续获得支持,因此我将添加来自其他答案的新信息,但也保留原始答案。
在评论中让我知道哪种解决方案适合您。
选项 1. 设置默认标题
在要导入 Axios 的文件中,设置默认标题:
选项 2. 手动将其添加到 Axios 调用中
假设您将令牌的值存储在名为
csrfToken
的变量中。在您的 axios 调用中设置标题:选项 3. 在调用中设置
xsrfHeaderName
:添加这个:
然后在您的
settings.py
文件中,添加以下行:编辑( _2017 年 6 月 10 日_):用户 @yestema 说它与 Safari [2]的工作方式略有不同
编辑( _2019 年 4 月 17 日_):用户 @GregHolst 说上面的 Safari 解决方案对他不起作用。相反,他在 MacOS Mojave 上为 Safari 12.1 使用了上述解决方案 #3。 ( _来自评论_)
编辑( _2019 年 2 月 17 日_):您可能还需要设置[3] :
我试过的东西不起作用: 1