jinja2模板引擎中如何进行csrf_token保护?

问题描述 投票:0回答:7

在 Django 模板中我使用:

<form action="/user" method="post">{% csrf_token %}
    {{ form.as_p|safe }}
    <input type="submit" value="Submit" />
</form>

但是当我更改为

jinja2 template engine
时出错:

 Encountered unknown tag 'csrf_token'

我的问题:

csrf_token protection
中的
jinja2
是必需的吗?

如果需要,该怎么做?

提前致谢!

django csrf jinja2
7个回答
53
投票

是的,您仍然想使用跨站点请求伪造保护,但 Jinja2 的工作方式略有不同。

而不是默认的 Django 模板语言字符串:

{% csrf_token %}

您可以将其替换为 Jinja2,它具有与输出完整隐藏 HTML 输入元素相同的行为:

{{ csrf_input }}

您还可以在 Jinja2 模板中单独使用

{{ csrf_token }}
来获取 CSRF 令牌本身并手动创建您自己的表单字段,例如:

<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">

原帖

文档


36
投票

我知道这是一个老问题,但我想用正确的方式更新它,以在使用 Django 1.8+ 中提供的新

csrf_token
时支持
django.template.backends.jinja2.Jinja2
。 使用 django 模板后端,您将调用
{% csrf_token %}
,但使用 Jinja2 后端,您将使用
{{ csrf_input }}
调用它(您可以使用
{{ csrf_token }}
仅获取令牌值,而不是令牌输入)。

您可以在

django.template.backends.jinja2.Jinja2
来源

查看详细信息

3
投票

在带有 jinja2 模板引擎的 django 2.x 中,您可以使用 {{ csrf_token }} 获取令牌的值,并使用 {{ csrf_input }} 获取完整的隐藏输入标记

来源:https://django.readthedocs.io/en/2.1.x/ref/csrf.html

示例:

<form action="..." method="post">
  {{ csrf_input }}

   ...
</form>

0
投票

我用棺材。 使用时也遇到同样的问题:

from coffin.shortcuts import render_to_response
return render_to_response('template_name_here.html', context)

尝试使用:

from coffin.shortcuts import render
return render(request, 'template_name_here.html', context)

0
投票

您不再需要做任何特别的事情。 csrf_token 在 django-jinja 中受支持并且开箱即用。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>test</title>
  </head>
  <body>
    <p>This should add a hidden input tag with the token. use it in your forms</p>
    {% csrf_token %}
  </body>
</html>

0
投票

这段 JS 代码可以解决这个问题,它适用于 Django 和 Jinja2, 因为是纯javaScript对post方法表单标签的处理,小伙伴们可以自行探索一下

我只是从已经存在的cookie中获取CSRF令牌,并在表单标签中使用它

let 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;
}


$(()=>{
    formTags = document.querySelectorAll('[method="POST"]')
    
    let csrfToken = getCookie('csrftoken')

    

    Array.from(formTags).forEach(formTag=>{

        var inputTag = document.createElement('input')

        inputTag.setAttribute('type', 'hidden')
        inputTag.setAttribute('name', 'csrfmiddlewaretoken')
        inputTag.setAttribute('value', [csrfToken])
    
        formTag.appendChild(inputTag)

    })
})

-1
投票

我遇到了同样的问题,我注意到 CSRF 上下文处理器不在默认加载的处理器列表中。将

'django.core.context_processors.csrf'
添加到
TEMPLATE_CONTEXT_PROCESSORS
中的
setting.py
后,我可以正常使用
{% csrf_token %}
模板标签。

© www.soinside.com 2019 - 2024. All rights reserved.