我以前在Django
. 如果{csrf_token}
在Django
模板中添加行,则Django
处理csrf_token
. 但是当我尝试使用Django REST Framework
然后开发 API 时,我被卡住了。我如何添加和处理像 Django 模板这样csrf_token
的API
(后端,使用开发的Django REST Framework
)和React Native/React JS
(前端)的功能?
如何在 Django RESTful API 和 React 中使用 csrf_token?
第一步是获取可以从 Django csrftoken cookie 中检索的 CSRF 令牌。
现在,您可以从Django 文档中了解如何使用这个简单的 JavaScript 函数从 cookie 中获取 csrf 令牌:
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 = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
现在,您可以通过调用该getCookie('csrftoken')
函数来检索 CSRF 令牌
var csrftoken = getCookie('csrftoken');
接下来,您可以通过将检索到的令牌分配给 X-CSRFToken 标头,在使用 fetch() 发送请求时使用此 csrf 令牌。
fetch(url, {
credentials: 'include',
method: 'POST',
mode: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken
},
body: {}
})
}
在 React Forms 中渲染 CSRF 令牌:
如果您使用 React 来呈现表单而不是 Django 模板,您还需要呈现 csrf 令牌,因为 Django 标记{ % csrf_token % }
在客户端不可用,因此您需要创建一个使用该getCookie()
函数检索令牌并呈现它的高阶组件以任何形式。
让我们在csrftoken.js
文件中添加一些行。
import React from 'react';
var csrftoken = getCookie('csrftoken');
const CSRFToken = () => {
return (
<input type="hidden" name="csrfmiddlewaretoken" value={csrftoken} />
);
};
export default CSRFToken;
然后你可以简单地导入它并在你的表单中调用它
import React, { Component , PropTypes} from 'react';
import CSRFToken from './csrftoken';
class aForm extends Component {
render() {
return (
<form action="/endpoint" method="post">
<CSRFToken />
<button type="submit">Send</button>
</form>
);
}
}
export default aForm;
Django CSRF Cookie
React 动态渲染组件,这就是为什么如果您使用 React 渲染表单,Django 可能无法设置 CSRF 令牌 cookie。Django 文档是这样说的:
如果您的视图未呈现包含 csrftoken 模板标记的模板,Django 可能不会设置 CSRF 令牌 cookie。这在表单被动态添加到页面的情况下很常见。为了解决这种情况,Django 提供了一个视图装饰器来强制设置 cookie:ensurecsrf_cookie()。
为了解决这个问题,Django 提供了 ensurecsrfcookie 装饰器,你需要将它添加到你的视图函数中。例如:
from django.views.decorators.csrf import ensure_csrf_cookie
@ensure_csrf_cookie
def myview(request):
我在react中使用了 jquery for ajax,所以在这种情况下,这是一个解决方案:
let csrfcookie = function() { // for django csrf protection
let cookieValue = null,
name = "csrftoken";
if (document.cookie && document.cookie !== "") {
let cookies = document.cookie.split(";");
for (let i = 0; i < cookies.length; i++) {
let cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) == (name + "=")) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
};
$.ajax({
type: "POST",
beforeSend: function(request, settings) {
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
request.setRequestHeader("X-CSRFToken", csrfcookie());
}
},
.... /// other codes