Python 将CSRF令牌添加到硬编码的Django表单
我正在用Jekyll构建一个具有硬编码表单的静态页面,我正在将表单数据发送到Django服务器,我在生成Python 将CSRF令牌添加到硬编码的Django表单,python,django,jekyll,csrf,Python,Django,Jekyll,Csrf,我正在用Jekyll构建一个具有硬编码表单的静态页面,我正在将表单数据发送到Django服务器,我在生成CSRF令牌时遇到问题。我能将数据保存到数据库的唯一方法是,如果我使用一个静态csrf令牌,这是有漏洞的、毫无意义的 有没有更好的方法可以做到这一点? 这就是我想要的: <form method="POST" action="http://djangoserver" > {% csrf_token %} <!-- Doesn't work in Jekyll --&g
CSRF令牌时遇到问题。我能将数据保存到数据库的唯一方法是,如果我使用一个静态csrf令牌,这是有漏洞的、毫无意义的
有没有更好的方法可以做到这一点?
这就是我想要的:
<form method="POST" action="http://djangoserver" >
{% csrf_token %} <!-- Doesn't work in Jekyll -->
<input type="text" name="name" required id="id_name" maxlength="100>
</form>
{%csrf_令牌%}
您所尝试的是不可能的,使Jekyll静态页面具有某种动态性的唯一方法是使用javascript
您可以通过在Django中创建API来实现所需的功能,该API将创建CSRF令牌并返回它,然后您可以将其附加到表单中。这样,您将始终拥有动态CSRF,但我不建议通过网络发送CSRF令牌,因为这是不安全的
希望这有帮助,{%csrf\u token%}
不会工作,因为它是Django模板标记。硬编码csrfmiddlewaretoken也不起作用,因为此值会更改以提供安全性
我的博客上也有一个类似的问题,那就是杰基尔。在一个联系人页面上,我添加了一个普通的HTML表单,其中action
指向我的Django后端。对于这个视图,我使用@CSRF\u emption
装饰器删除了CSRF令牌验证
为了避免滥用,我添加了一个GoogleReCAPTCHA验证
请参见下面的示例:
from django.conf import settings
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
import requests # http://docs.python-requests.org
@require_POST
@csrf_exempt
def ask(request):
recaptcha_response = request.POST.get('g-recaptcha-response')
data = {
'secret': settings.GOOGLE_INVISIBLE_RECAPTCHA_SECRET_KEY,
'response': recaptcha_response
}
r = requests.post('https://www.google.com/recaptcha/api/siteverify', data=data)
result = r.json()
if result['success']:
# process form...
else:
# invalid recaptcha
如果这是而不是在同一个域上,我建议设置
如果它在同一个域上,则执行上建议的操作:您可以使用JavaScript获取CSRF令牌(注意,我已将函数更改为不使用jQuery):
添加csrftoken输入:
var form = document.getElementById('name-form'),
input = document.createElement('input');
input.name = "csrfmiddlewaretoken";
input.type = "hidden";
input.value = getCookie('csrftoken');
// ^ could be a different string depending on your settings.py file
form.appendChild(input);
希望这能有所帮助。聪明,没有想到这一点,因此表单位于一个域(GitHub页面)上,Django将托管在单独的主机上。我觉得js方法是最简单的,我是否可以在一台服务器上生成令牌并将其发送给Django,或者我必须为此制作api?我认为这是不可能的。如果可能的话,这不是一个好主意。在这种情况下,您应该在Django REST框架上阅读,并使用它为Django服务器创建API。然后您可以接受来自其他域名的请求。
// WITHOUT jQuery
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();
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
<form id="name-form" method="POST" action="http://djangoserver" >
<input type="text" name="name" required id="id_name" maxlength="100>
</form>
var form = document.getElementById('name-form'),
input = document.createElement('input');
input.name = "csrfmiddlewaretoken";
input.type = "hidden";
input.value = getCookie('csrftoken');
// ^ could be a different string depending on your settings.py file
form.appendChild(input);