向硬编码Django表单添加CSRF令牌

2024-04-27 13:35:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用Jekyll构建一个带有硬编码表单的静态页面,我正在将表单数据发送到Django服务器,生成CSRF token时遇到问题。我能把数据保存到数据库的唯一方法是使用一个静态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>

但是很明显,Jekyll不知道这个令牌是什么,POST不会将它发送到Django服务器。在


这是可行的,但它是脆弱的和黑客的,我需要同样的效果,实际上每次生成一个独特的令牌。在

^{pr2}$

Tags: 数据django方法nameform服务器tokenid
3条回答

如果这不在同一个域中,我建议设置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):

^{pr2}$

添加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静态页面具有某种动态性的唯一方法是使用javascript。在

您可以通过在Django中创建API来实现所需的内容,该API将创建CSRF令牌并返回它,然后可以将其附加到表单中。这样,您将始终拥有动态CSRF,但我不建议通过网络发送CSRF令牌,因为这是不安全的。在

希望有帮助

{% csrf_token %}无法工作,因为它是Django模板标记。硬编码csrfmiddlewaretoken也不起作用,因为这个值会更改以提供安全性。在

我的博客上也有类似的问题,那就是杰基尔。在一个联系人页面上,我添加了一个普通的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

相关问题 更多 >