【问题标题】:CSRF cookie not set django...verification failedCSRF cookie 未设置 django...验证失败
【发布时间】:2013-11-05 02:41:12
【问题描述】:

AoA 我是 Django 新手,我正在尝试从 POST 获取数据,但是没有设置错误 CSRF cookie,我也尝试了很多在 google 和 stackoverflow 上通过 google 找到解决方案,但失败了

这里是代码

views.py

    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 文件

<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

 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

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',
)

【问题讨论】:

    标签: python django cookies


    【解决方案1】:

    您似乎忘记传递渲染请求

    Django 带有一个特殊的 Context 类,django.template.RequestContext,它的行为与普通的 django.template.Context 略有不同。第一个区别是它将 HttpRequest 作为其第一个参数。例如:

    除了这些,RequestContext 总是使用 django.core.context_processors.csrf。这是管理员和其他 contrib 应用程序所需的与安全相关的上下文处理器,如果意外配置错误,它会被故意硬编码,并且不能通过 TEMPLATE_CONTEXT_PROCESSORS 设置关闭。

    所以你需要的是关注

    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

    【讨论】:

    • 你能解释一下吗?
    • 不,仍然收到错误 FORBIDDEN 403 'CSRF 验证失败。请求中止。失败原因:未设置 CSRF cookie。
    • 更改后是否重新加载页面?
    • 是的...我已经重新启动服务器并重新加载页面
    【解决方案2】:

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

    c = {}
    c.update(csrf(request))
    

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

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

    提供服务
    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' 之后添加一个逗号,现在的方式是连接字符串。

    应该是:

    TEMPLATE_CONTEXT_PROCESSORS = (
        'django.core.context_processors.csrf',
        'django.contrib.auth.context_processors.auth',
        'django.core.context_processors.debug',
    

    【讨论】:

    • 您在生成的 html 中看到 csrf 令牌吗?
    • 这个 ResponseContext 是什么?
    • 通过 urls.py 问题更新并使用了一个请求(你教了我很多)并呈现页面..仍然在 search.html 中缺少 csrf 字段并在单击 POST 时出现验证失败错误按钮...我为此做了另一种方法...检查上面...为什么要添加冒号? 'django.core.context_processors.csrf':,当我运行服务器时,它给了我一个错误列表
    • 问题已解决 :) 非常感谢您的帮助...我将其用于 GET t = get_template('home.html') c = RequestContext(request, {'name':name} ) 以及您在 POST 中提到的代码...这给了我错误,用 c = {'name': name} c.update(csrf(request)) 替换 get_template 解决了问题:) 再次感谢:)跨度>
    • 在这种情况下,我建议您将问题标记为已回答,或者从现有答案中选择,或者如果您觉得不合适,请添加自己的答案。
    【解决方案3】:

    从修复 HTML 开始(您忘记了 =):

    <form method="POST" action="/search/save">
    {% csrf_token %}
    <textarea name="content" rows="20" cols="60">{{content}}</textarea><br>
    <input type="submit" value="Save Page"/>
    </form>
    

    还有:

    def home_Page(request):
        #if request.method == 'GET':
        name='Awais you have visited my website :P'
        if request.method == 'POST':
            #name = request.POST.get('content')
            return render_to_response("search.html", {}, context_instance=RequestContext(request))
    
        return render_to_response("home.html", {'name':name}, context_instance=RequestContext(request))
    

    【讨论】:

    • 我已通过更正“action=”并用我的代码替换您的代码来更新我的问题,它可以通过 GET 完美运行,但是当我单击表单按钮时,它给了我错误...cookie 未设置...CSRF 验证失败
    • 检查呈现的页面。您是否渲染了 csrf 字段(隐藏输入)?
    • html页面没有csrf字段
    【解决方案4】:

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

     from django.views.decorators.csrf import ensure_csrf_cookie
     @ensure_csrf_cookie
     def yourView(request):
         #...
    

    它将在浏览器cookie中设置csrftoken,你可以像这样制作ajax

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

    【讨论】:

    • 哇!这对我有用,因此可以在您的网站上保留 csrf 保护,对吗?
    【解决方案5】:

    尝试使用带有端口号而不是 DNS 的确切 IP 地址...例如使用 127.0.0.1 和端口号代替 localhost。 p>

    【讨论】:

    • 这与问题无关。除此之外,您还错误地使用了 DNS 一词。使用 IP 地址代替主机名没有任何意义。
    猜你喜欢
    • 2013-05-12
    • 2012-09-08
    • 2015-06-02
    • 1970-01-01
    • 2021-06-22
    • 1970-01-01
    相关资源
    最近更新 更多