Search code examples
pythondjangoresttastypie

Does SessionAuthentication work in Tastypie for HTTP POST?


I am able to do GET to work with SessionAuthentication and Tastypie without setting any headers except for content-type to application/json. HTTP POST however just fails even though the Cookie in the Header has the session id. It fails with a 401 AuthorizationHeader but it has nothing to do with Authorization. Changing SessionAuthentication to BasicAuthentication and passing username/password works too.

Has anyone ever got SessionAuthentication to work with POST with Tastypie?


Solution

  • Yes I have gotten it to work. All you need to do is to pass the csfr token:

    SessionAuthentication

    This authentication scheme uses the built-in Django sessions to check if a user is logged. This is typically useful when used by Javascript on the same site as the API is hosted on.

    It requires that the user has logged in & has an active session. They also must have a valid CSRF token.

    This is how you do that in jQuery:

    // sending a csrftoken with every ajax request
    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", $.cookie('csrftoken'));
            }
        }
    });
    
    $.ajax({
        type: "POST",
        // ...
    

    Notice the part that says $.cookie('csrftoken'). It gets the csrf token from a cookie that Django sets.

    Update:

    I had some problems with Django not setting the cookie on Firefox and Opera. Putting the template tag {% csrf_token %} in your template solves this. The right solution would probably be to use the decorator ensure_csrf_cookie().