CSRF与Django,React + Redux使用Axios [英] CSRF with Django, React+Redux using 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.
Things I tried that didn't work: 1, 2
这篇关于CSRF与Django,React + Redux使用Axios的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!