首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CSRF cookie未设置django...verification失败

CSRF cookie未设置django...verification失败
EN

Stack Overflow用户
提问于 2013-10-26 04:35:44
回答 5查看 18.7K关注 0票数 4

AoA我是Django的新手,我正在尝试从POST中获取数据,但没有设置错误的CSRF cookie,我尝试了很多次在谷歌上找到解决方案,并通过谷歌堆栈溢出,但失败了

以下是代码

views.py

代码语言:javascript
复制
    from django.http import HttpResponse
    from django.template.loader import get_template
    from django.template import Context
    from django.template import RequestContext
    from django.core.context_processors import csrf
    from django.shortcuts import render_to_response

def search_Post(request):
    if request.method == 'POST':
            c = {}
        c.update(csrf(request))
        # ... view code here
                return render_to_response("search.html", c)

def search_Page(request):
    name='Awais you have visited my website :P'
    t = get_template('search.html')
    html = t.render(Context({'name':name}))
    return HttpResponse(html)

HTML文件

代码语言:javascript
复制
<p>
          {{ name }}
            <form method="POST" action="/save/">
              {% csrf_token %}
              <textarea name="content" rows="20" cols="60">{{content}}</textarea><br>
              <input type="submit" value="Save Page"/>
            </form>
       <div>  Cant figure out any solution! :( </div>

 </p>

url.py

代码语言:javascript
复制
 url(r'^home/$', 'contacts.views.home_Page'),
 url(r'^save/$', 'contacts.views.search_Post'),
 url(r'^edit/$', 'contacts.views.edit_Page'),
 url(r'^search/$', 'contacts.views.search_Page'),

settings.py

代码语言:javascript
复制
TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.csrf',
    'django.contrib.auth.context_processors.auth',
    'django.core.context_processors.debug',
    'django.core.context_processors.i18n',
    'django.core.context_processors.media',
    'django.core.context_processors.static',
    'django.core.context_processors.request',
    'django.contrib.messages.context_processors.messages'
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    # Uncomment the next line for simple clickjacking protection:
    # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
EN

回答 5

Stack Overflow用户

发布于 2014-05-21 23:23:47

我也遇到了同样的问题,并通过将ensure_csrf_cookie decorator添加到您的视图中来解决它:

代码语言:javascript
复制
 from django.views.decorators.csrf import ensure_csrf_cookie
 @ensure_csrf_cookie
 def yourView(request):
     #...

它将在浏览器cookie中设置csrftoken,您可以这样设置ajax

代码语言:javascript
复制
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]);
            // 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;
}
function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
    crossDomain: false, // obviates need for sameOrigin test
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type)) {
            xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
        }
    }
});
$.ajax({
        url: url,
        type: type,
        async: async,
        data: data,
        error: function (e) {},
        success: function (data) {
                returnFunction(data);
            }
    });
票数 8
EN

Stack Overflow用户

发布于 2013-10-26 04:43:24

您可以使用这两种方法将CSRF令牌传递给模板处理器

代码语言:javascript
复制
c = {}
c.update(csrf(request))

RequestContext,而一个就足够了,see docs。但是你把它用错了地方,用来处理'POST‘请求。这些请求通常由您的浏览器在填写表单并希望获得结果时发送。

您的浏览器将发送GET请求的home.html呈现给服务器,该服务器由

代码语言:javascript
复制
t = get_template('home.html')
html = t.render(ResponseContext({'name':name}))
return HttpResponse(html)

你代码的一部分。在这里,你不能使用任何方法来传递csrf 。因此,当您的模板处理器get_template().render()被调用时,它的上下文中没有标记,因此简单地忽略模板中的{% csrf_token %}代码。因此,您必须在t.render中使用RequestContext (...)视图的一部分,或者在那里传递给你c dict。

您可以在浏览器窗口中检查生成的表单来检查它。

更新

seetings.py中,在'django.core.context_processors.csrf'后面添加一个逗号,按照现在的方式,它只是连接字符串。

应该是:

代码语言:javascript
复制
TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.csrf',
    'django.contrib.auth.context_processors.auth',
    'django.core.context_processors.debug',
票数 5
EN

Stack Overflow用户

发布于 2013-10-26 04:40:10

您似乎忘记了传递呈现的请求

Django附带了一个特殊的上下文类django.template.RequestContext,它的行为与普通的django.template.Context略有不同。第一个不同之处在于,它以HttpRequest作为第一个参数。例如:

除此之外,RequestContext始终使用django.core.context_processors.csrf。这是管理员和其他contrib应用程序所需的安全相关上下文处理器,在意外错误配置的情况下,它是故意硬编码的,无法通过TEMPLATE_CONTEXT_PROCESSORS设置关闭。

因此,您需要的是以下内容

代码语言:javascript
复制
t = get_template('home.html')
c = RequestContext(request, {'name':name})
return HttpResponse(t.render(c))

如果你喜欢,你可以在这里查看django dock https://docs.djangoproject.com/en/dev/ref/templates/api/#django.template.RequestContext

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19598993

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档