CSRF cookie未设置django ...验证失败

时间:2022-06-01 16:56:57

AoA I am new to Django, I am trying to get data from POST, but getting error CSRF cookie not set, I tried alot to find the solution on google and * via google too, but failed

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

here is the code

这是代码

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 File

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

5 个解决方案

#1


7  

I had the same problem, and resolved it by adding the ensure_csrf_cookie decorator to your view:

我有同样的问题,并通过在您的视图中添加ensure_csrf_cookie装饰器来解决它:

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

It will set csrftoken in browser cookie and you can make ajax like this

它将在浏览器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);
            }
    });

#2


4  

You use both means to pass CSRF token to template processor

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

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

and RequestContext, while one is enough, see docs. But you use it wrong place, for serving 'POST' request. Those requests are normally sent by your browser when it fills up a form and want to get results.

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

Your browser renders home.html sending GET request to a server, which is served by

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

t = get_template('home.html')
html = t.render(ResponseContext({'name':name}))
return HttpResponse(html)

part of your code. And there you do not use any mean to pass csrf token. So when your template processor get_template().render() is invoked, is has no token in its context, so simply ignores {% csrf_token %} code in template. So you have to either use RequestContext in t.render(...) part of view, or pass you c dict there.

部分代码。在那里你不使用任何手段来传递csrf令牌。因此,当调用模板处理器get_template()。render()时,其上下文中没有令牌,因此只需忽略模板中的{%csrf_token%}代码。所以你必须在t.render(...)部分视图中使用RequestContext,或者在那里传递c dict。

You can check it inspecting generated form in a browser window.

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

UPDATE

UPDATE

In seetings.py add a comma after 'django.core.context_processors.csrf', the way it is now, it just contcatenates strings.

在seetings.py中,在'django.core.context_processors.csrf'之后添加一个逗号,就像现在一样,它只是连接字符串。

Should be:

应该:

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

#3


1  

Start from fixing your HTML (You forgot =):

从修复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>

Also:

也:

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

#4


1  

It seems that You have forgot to pass request to render

看来你忘了传递渲染请求了

Django comes with a special Context class, django.template.RequestContext, that acts slightly differently than the normal django.template.Context. The first difference is that it takes an HttpRequest as its first argument. For example:

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

In addition to these, RequestContext always uses django.core.context_processors.csrf. This is a security related context processor required by the admin and other contrib apps, and, in case of accidental misconfiguration, it is deliberately hardcoded in and cannot be turned off by the TEMPLATE_CONTEXT_PROCESSORS setting.

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

So What You need is following

所以你需要的是以下

t = get_template('home.html')
c = RequestContext(request, {'name':name})
return HttpResponse(t.render(c))

If You wold like You can check django dock here https://docs.djangoproject.com/en/dev/ref/templates/api/#django.template.RequestContext

如果你喜欢你可以检查django停靠这里https://docs.djangoproject.com/en/dev/ref/templates/api/#django.template.RequestContext

#5


-4  

Try using the exact IP address with the port number instead of the DNS... Like instead of localhost use 127.0.0.1 along with the port number.

尝试使用确切的IP地址和端口号而不是DNS ...像localhost一样使用127.0.0.1和端口号。

#1


7  

I had the same problem, and resolved it by adding the ensure_csrf_cookie decorator to your view:

我有同样的问题,并通过在您的视图中添加ensure_csrf_cookie装饰器来解决它:

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

It will set csrftoken in browser cookie and you can make ajax like this

它将在浏览器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);
            }
    });

#2


4  

You use both means to pass CSRF token to template processor

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

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

and RequestContext, while one is enough, see docs. But you use it wrong place, for serving 'POST' request. Those requests are normally sent by your browser when it fills up a form and want to get results.

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

Your browser renders home.html sending GET request to a server, which is served by

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

t = get_template('home.html')
html = t.render(ResponseContext({'name':name}))
return HttpResponse(html)

part of your code. And there you do not use any mean to pass csrf token. So when your template processor get_template().render() is invoked, is has no token in its context, so simply ignores {% csrf_token %} code in template. So you have to either use RequestContext in t.render(...) part of view, or pass you c dict there.

部分代码。在那里你不使用任何手段来传递csrf令牌。因此,当调用模板处理器get_template()。render()时,其上下文中没有令牌,因此只需忽略模板中的{%csrf_token%}代码。所以你必须在t.render(...)部分视图中使用RequestContext,或者在那里传递c dict。

You can check it inspecting generated form in a browser window.

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

UPDATE

UPDATE

In seetings.py add a comma after 'django.core.context_processors.csrf', the way it is now, it just contcatenates strings.

在seetings.py中,在'django.core.context_processors.csrf'之后添加一个逗号,就像现在一样,它只是连接字符串。

Should be:

应该:

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

#3


1  

Start from fixing your HTML (You forgot =):

从修复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>

Also:

也:

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

#4


1  

It seems that You have forgot to pass request to render

看来你忘了传递渲染请求了

Django comes with a special Context class, django.template.RequestContext, that acts slightly differently than the normal django.template.Context. The first difference is that it takes an HttpRequest as its first argument. For example:

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

In addition to these, RequestContext always uses django.core.context_processors.csrf. This is a security related context processor required by the admin and other contrib apps, and, in case of accidental misconfiguration, it is deliberately hardcoded in and cannot be turned off by the TEMPLATE_CONTEXT_PROCESSORS setting.

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

So What You need is following

所以你需要的是以下

t = get_template('home.html')
c = RequestContext(request, {'name':name})
return HttpResponse(t.render(c))

If You wold like You can check django dock here https://docs.djangoproject.com/en/dev/ref/templates/api/#django.template.RequestContext

如果你喜欢你可以检查django停靠这里https://docs.djangoproject.com/en/dev/ref/templates/api/#django.template.RequestContext

#5


-4  

Try using the exact IP address with the port number instead of the DNS... Like instead of localhost use 127.0.0.1 along with the port number.

尝试使用确切的IP地址和端口号而不是DNS ...像localhost一样使用127.0.0.1和端口号。