3

form.html

<form action='/login/' method = 'post'>
    {% csrf_token %}
    <label>Email: (*)</label><input type='text' name='email' value='' /><br />
    <label>Password: </label><input type='password' name='password' value='' /><br />
    <input type='submit' name='submit' value='Log in' />
</form>

and views.py i use HttpResponse not render_to_response

def login(request):
    success = False
    message = ''

    try:
        emp = Employee.objects.get(email = request.POST['email'])
        if emp.password == md5.new(request.POST['password']).hexdigest() :
            emp.token = md5.new(request.POST['email'] + str(datetime.now().microsecond)).hexdigest()
            emp.save()
            info = serializers.serialize('json', Employee.objects.filter(email = request.POST['email']))
            success = True
            return HttpResponse(json.dumps({'success':str(success).lower(), 'info':info}))
        else:
            message = 'Password wrong!'
            return HttpResponse(json.dumps({'success':str(success).lower(), 'message':message}), status = 401)
    except:
        message = 'Email not found!'
        return HttpResponse(json.dumps({'success':str(success).lower(), 'message':message}), status = 401)

if use render_to_response, i just add RequestContext but HttpResponse, i don't know what to do.

i use Django 1.4
Where's my problem

=========================

My problem is sloved when I change the function that render the HTML :

def homepage(request):
    return render_to_response('index.html')

to

def homepage(request):
    return render_to_response('index.html', context_instance=RequestContext(request))

That's a stupid mistake... thanks...

Bàn Chân Trần
  • 1,890
  • 2
  • 21
  • 24
  • You need to provide the view code for the view that is rendering the form, not the one that is handling the post. – Thomas Orozco Jun 22 '12 at 08:39
  • 1
    From the fact that you're returning JSON, I'm guessing you're submitting this form with an AJAX post? If so, you might want to read this: https://docs.djangoproject.com/en/1.4/ref/contrib/csrf/#ajax – Ian R.B. Jun 22 '12 at 08:57
  • 1
    How is `form.html` getting rendered? You have no reference to it in your view. – Daniel Roseman Jun 22 '12 at 09:23
  • @DanielRoseman : when i submit form, function 'login' will be call by url.py – Bàn Chân Trần Jun 22 '12 at 09:30
  • Do you have `csrfmiddlewaretoken` in `request.POST`? And is it rendered (like ``)? – DrTyrsa Jun 22 '12 at 09:35
  • @user1448311 I can't imagine how you think that answers my question. What renders the HTML? The CSRF token needs to be included in the view function that renders the HTML. You haven't shown that view function. – Daniel Roseman Jun 22 '12 at 09:39
  • @DanielRoseman sorry for my answer... i made a mistake stupid. i forgot use requestcontext when render the HTML. – Bàn Chân Trần Jun 22 '12 at 09:58
  • What Django version do you use? Why not to use [render](https://docs.djangoproject.com/en/dev/topics/http/shortcuts/#render)? – DrTyrsa Jun 22 '12 at 10:10

2 Answers2

2

If you are using ajax to send the form and have included jQuery, you have two possibilities:

  1. Manually add the csrfmiddlewaretoken data to your POST request
  2. Automate CSRF token handling by modifying jQuery ajax request headers

1. Manually add csrfmiddlewaretoken

var data = {
    csrfmiddlewaretoken: $('#myForm input[name=csrfmiddlewaretoken]').val(),
    foo: 'bar',
};

$.ajax({
    type: 'POST',
    url: 'url/to/ajax/',
    data: data,
    dataType: 'json',
    success: function(result, textStatus, jqXHR) {
        // do something with result
    },
});

2. Automate CSRF token handling

jQuery(document).ajaxSend(function(event, xhr, settings) {
    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 sameOrigin(url) {
        // url could be relative or scheme relative or absolute
        var host = document.location.host; // host + port
        var protocol = document.location.protocol;
        var sr_origin = '//' + host;
        var origin = protocol + sr_origin;
        // Allow absolute or scheme relative URLs to same origin
        return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
            (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
            // or any other URL that isn't scheme relative or absolute i.e relative.
            !(/^(\/\/|http:|https:).*/.test(url));
    }
    function safeMethod(method) {
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }

    if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
        xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
    }
});

But: It is said that modifying the ajax request headers is bad practice. Therefore i'd go with solution number one.

Source: Cross Site Request Forgery protection: AJAX

Alp
  • 29,274
  • 27
  • 120
  • 198
  • please write an answer to your own question and accept it so that other people can benefit from your insights – Alp Jun 22 '12 at 10:10
  • that's good, but it would be even better if you put that to an answer and accept it, that's the way stackoverflow works :) – Alp Jun 22 '12 at 10:19
-3

The Django Documentations (CSRF DOC LINK) clearly explains how to enable it.

This should be the basic way of writing view with csrf token enabled..

from django.views.decorators.csrf import csrf_protect

@csrf_protect
def form(request):
    if request.method == 'GET':
            #your code
            context = {}
            return render (request, "page.html", context )
Surya
  • 4,824
  • 6
  • 38
  • 63
  • 1
    OP was asking not how to disable CSRF but how to make it work properly. – jb. Jun 22 '12 at 09:06
  • @jb. Sorry. Its a valid mistake.. I was just copying some code from my disk. – Surya Jun 22 '12 at 09:09
  • csrf_exempt(view) - This decorator marks a view as being exempt from the protection ensured by the middleware. does it mean disable CSRF protection? – Bàn Chân Trần Jun 22 '12 at 09:12
  • @user1448311 why don't you check whether `django.middleware.csrf.CsrfViewMiddleware` is enabled in your settings – Surya Jun 22 '12 at 09:21