0

I am having problem for ajax posts to my django ecommerce site after user login. The failing scenario is as follows:

1-) User comes to site and adds products to shopping cart without any problem. Adding product to cart is an ajax call and the code is as follows:

    function addItemToCart(item_pk, quantity) {
      var item_quantity;

      if (!quantity) {
        item_quantity = 1;
      } else {
        item_quantity = quantity;
      }

      $.ajaxSetup({
        beforeSend: function(xhr) {
          xhr.setRequestHeader('Csrf-Token', csrftoken);
        }
      });

      $.ajax({
        type: 'POST',
        url: '/api/cart/add-item/',
        data: {
          item: item_pk,
          quantity: item_quantity
        }
        success: function(data, textStatus, jQxhr) {
          updateCart();
        },
        error: function(jqXhr, textStatus, errorThrown) {
          console.log(jqXhr, textStatus, errorThrown);
        }
      });
    }

The above code works perfectly and user can add several products to the cart.

2-) After that the user logs in to the site to make the payment, but before he make the payment he wanted to add another product to the cart, but the code fails.

3-) The error message is as follows: "CSRF Failed: CSRF token missing or incorrect."

When I checked the request I see that the ajax call already set the csrf token. The only thing I figured out is that django has refreshed the token after user login. But I also make sure that ajax call has been set csrf header with the new one.

So, I am confused why it works before user login and it does not work after user login. Because both posts has been made with the correct csrf tokens.

Any idea about what am i missing?

kempo
  • 91
  • 5
  • possible duplicate of https://stackoverflow.com/questions/33882819/csrf-token-missing-or-invalid-django – Abhishek Feb 22 '19 at 15:04

2 Answers2

2

This is happening because Django uses csrf verification on POST requests, and your AJAX function is not properly passing csrf verification information. The Django docs have a good section on this that outlines some additional jQuery function you'll need to include to make a successful AJAX post using Django.

Sam
  • 1,952
  • 1
  • 18
  • 31
  • It works if the user has not logged in. There is no any missing part for the post – kempo Feb 22 '19 at 14:02
  • Sorry Sam, you are right the problem was the cookie name. It should be xhr.setRequestHeader('X-CSRFToken', csrftoken);. But still I don't understand why it works with the xhr.setRequestHeader('Csrf-Token', csrftoken); line (for offline users) – kempo Feb 22 '19 at 15:15
  • @kempo Because the token is only checked for authenticated users, see https://stackoverflow.com/a/30875830/6280433 – Endre Both Feb 22 '19 at 19:23
0

I have solved the problem:

The problem was the token header name. I was using the header name as 'Csrf-Token' and I still do not understand why it works for offline users but, it should be ''X-CSRFToken'. Maybe it is a bug for Django 2, I don't know.

kempo
  • 91
  • 5