带有Django的CSRF,使用Axios的React + Redux
这是一个教育项目,不用于生产。我本来不想让用户登录。
我可以在没有用户登录的情况下使用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},
// ...
- xsrfHeaderName在通话中设置:
- 添加此:
// ...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
以上是 带有Django的CSRF,使用Axios的React + Redux 的全部内容, 来源链接: utcz.com/qa/425060.html