Saad Abdullah
Saad Abdullah

Reputation: 2452

CSRF cookie not set django...verification failed

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 stackoverflow via google too, but failed

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

Upvotes: 4

Views: 20144

Answers (5)

Yoganand
Yoganand

Reputation: 340

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

 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

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

Upvotes: 9

impiyush
impiyush

Reputation: 794

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.

Upvotes: -4

alko
alko

Reputation: 48357

You use both means to pass CSRF token to template processor

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.

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

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.

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

UPDATE

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

Should be:

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

Upvotes: 5

oleg
oleg

Reputation: 4182

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:

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.

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

Upvotes: 1

Dmitry Demidenko
Dmitry Demidenko

Reputation: 3407

Start from fixing your HTML (You forgot =):

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

Upvotes: 1

Related Questions