将 CSRF 令牌添加到硬编码的 Django 表单
Add CSRF token to hard coded Django form
我正在使用 Jekyll 构建一个具有硬编码表单的 静态页面,我正在将表单数据发送到 Django 服务器,我在生成 CSRF token
.我可以将数据保存到数据库的唯一方法是使用静态的 csrf 令牌,它是 hacky 且毫无意义的。
有更好的方法吗?
这就是我想要的:
<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>
但显然 Jekyll 不知道该令牌是什么,POST 不会将其发送到 Django 服务器。
这行得通,但它很容易受到攻击而且很老套,我需要每次都实际生成唯一令牌的相同效果。
<form method="POST" action="http://djangoserver" >
<input type="hidden" name="csrfmiddlewaretoken" value=" some long stuff" >
<input type="text" name="name" required id="id_name" maxlength="100>
</form>
你的尝试是不可能的,让 Jekyll 静态页面有点动态的唯一方法是使用 JavaScript.
您可以通过在 Django 中创建 API 来实现您想要的,这将创建 CSRF 令牌并 return 然后您可以将其附加到您的表单中。这样您将始终拥有动态 CSRF,但是我不建议跨网络发送 CSRF 令牌,因为它不安全。
{% csrf_token %}
将不起作用,因为它是 Django 模板标签。硬编码 csrfmiddlewaretoken
也不起作用,因为此值会更改以提供安全性。
我的博客 Jekyll 也有类似的问题。在联系页面上,我添加了正常的 HTML 表单,其中 action
指向我的 Django 后端。对于此视图,我使用 @csrf_exempt
装饰器删除了 CSRF 令牌验证。
为了避免滥用,我添加了 Google Recaptcha 验证。
看下面的例子:
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
如果这 不是 在同一个域上,我建议设置 Django REST Framework。
如果在同一个域,那么按照Django Docs上的建议做:你可以用JavaScript获取CSRF令牌(注意我已经更改了要在没有 jQuery 的情况下使用的功能):
// 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;
}
更新表格(注意id
):
<form id="name-form" method="POST" action="http://djangoserver" >
<input type="text" name="name" required id="id_name" maxlength="100>
</form>
添加 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);
希望对您有所帮助。
我正在使用 Jekyll 构建一个具有硬编码表单的 静态页面,我正在将表单数据发送到 Django 服务器,我在生成 CSRF token
.我可以将数据保存到数据库的唯一方法是使用静态的 csrf 令牌,它是 hacky 且毫无意义的。
有更好的方法吗?
这就是我想要的:
<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>
但显然 Jekyll 不知道该令牌是什么,POST 不会将其发送到 Django 服务器。
这行得通,但它很容易受到攻击而且很老套,我需要每次都实际生成唯一令牌的相同效果。
<form method="POST" action="http://djangoserver" >
<input type="hidden" name="csrfmiddlewaretoken" value=" some long stuff" >
<input type="text" name="name" required id="id_name" maxlength="100>
</form>
你的尝试是不可能的,让 Jekyll 静态页面有点动态的唯一方法是使用 JavaScript.
您可以通过在 Django 中创建 API 来实现您想要的,这将创建 CSRF 令牌并 return 然后您可以将其附加到您的表单中。这样您将始终拥有动态 CSRF,但是我不建议跨网络发送 CSRF 令牌,因为它不安全。
{% csrf_token %}
将不起作用,因为它是 Django 模板标签。硬编码 csrfmiddlewaretoken
也不起作用,因为此值会更改以提供安全性。
我的博客 Jekyll 也有类似的问题。在联系页面上,我添加了正常的 HTML 表单,其中 action
指向我的 Django 后端。对于此视图,我使用 @csrf_exempt
装饰器删除了 CSRF 令牌验证。
为了避免滥用,我添加了 Google Recaptcha 验证。
看下面的例子:
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
如果这 不是 在同一个域上,我建议设置 Django REST Framework。
如果在同一个域,那么按照Django Docs上的建议做:你可以用JavaScript获取CSRF令牌(注意我已经更改了要在没有 jQuery 的情况下使用的功能):
// 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;
}
更新表格(注意id
):
<form id="name-form" method="POST" action="http://djangoserver" >
<input type="text" name="name" required id="id_name" maxlength="100>
</form>
添加 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);
希望对您有所帮助。