Search code examples
ajaxodoo-12csrf-token

Odoo 12 - Invalid CSRF Token with AJAX for adding to wishlist


I'm currently working as a developer for a company and its website is based on Odoo 12. Everything worked great even if this system is... complicated to work at for your first intership.

Firstly I'll explain why I want this, what are my restrictions and I made at this point.

  1. I'm currently working on a configurator (for a computer) and it works! Now's the time to add to the cart if in stock (it works) and to add to the Wishlist if not (here's the problem).
  2. Well for the restrictions, I don't have access to the python side nor code. ONLY the XML (HTML and CSS) from the models (but I can create them). Hence, I'm making all the work with the server side XML/HTML and JS. Again it works.
  3. That's why the code I'll show is in JS (with AJAX):
// Add to cart
function cookieConfigAddToCart() {
    // [ID][isInStock]
    // 12671 is 'montage'
    let cookieSelectedIds = [['12671', true]];

    // for each selected products, push his ID in the 'cookieSelectedIds'
    for (let i = cookieSelectedProducts.length - 1; i >= 0; i--) {
        if (cookieSelectedProducts[i].hasAttribute('p-id')) {
            cookieSelectedIds.push([
                cookieSelectedProducts[i].getAttribute('p-id'),
                cookieSelectedProducts[i].getAttribute('p-isinstock') === 'true'
            ]);
        }
    }

    console.log(cookieSelectedIds);
    // For each selected products, send a query
    // to the server to update the cart
    if (cookieSelectedIds.length > 1) {
        for (let i = cookieSelectedIds.length - 1; i >= 0; i--) {
            let errorAddToCart = false;

            if (cookieSelectedIds[i][1]) {
                $.ajax({
                    async: false,
                    type: 'POST',
                    url: '/shop/cart/update',
                    data: {
                        csrf_token: document.getElementById('cookieConfigAddToCartToken').innerHTML,
                        product_id: cookieSelectedIds[i][0]
                    },
                    success: function() {
                        console.log(i+": OK (CART)");
                    },
                    error: function() {
                        for (let y = cookieSelectedProducts.length - 1; y > 0; y--) {
                            if (cookieSelectedProducts[y].getAttribute('p-id') == cookieSelectedIds[i][0]) {
                                console.error(
                                    "Il y a eu une erreur pendant l'envoi au serveur du produit: "
                                    + cookieSelectedProducts[y].innerHTML
                                );
                                console.log("Veuillez réessayer ultérieurement");
                                break;
                            }
                        }
                    },
                });
            }
            else {
                $.ajax({
                    async: false,
                    type: 'POST',
                    url: '/shop/wishlist/add',
                    data: {
                        id: document.getElementById('cookieConfigAddToCartToken').innerHTML,
                        jsonrpc: "2.0",
                        method: "call",
                        params: '{product_id: '+cookieSelectedIds[i][1]+'}'
                    },
                    success: function() {
                        console.log(i+": OK (WISHLIST)");
                    },
                    error: function() {
                        for (let y = cookieSelectedProducts.length - 1; y > 0; y--) {
                            if (cookieSelectedProducts[y].getAttribute('p-id') == cookieSelectedIds[i][0]) {
                                console.error(
                                    "Il y a eu une erreur pendant l'envoi au serveur du produit: "
                                    + cookieSelectedProducts[y].innerHTML
                                );
                                console.log("Veuillez réessayer ultérieurement");
                                break;
                            }
                        }
                    },
                });
            }

        }

        // window.location.href = "/shop/cart/";
    }
}

So the 'cart' part works well (url: '/shop/cart/update',) but not the 'wishlist' one (url: '/shop/wishlist/add').

And I'm lost At the CSRF Token of the wishlist. The official way uses a 9 digits one but I don't know how to find/get it.

With an old 9 digits one or the one I'm currently using, I have (without surprises) these messages:

Traceback (most recent call last):
  File "/home/odoo/src/odoo/odoo/addons/base/models/ir_http.py", line 234, in _dispatch
    result = request.dispatch()
  File "/home/odoo/src/odoo/odoo/http.py", line 807, in dispatch
    raise werkzeug.exceptions.BadRequest('Session expired (invalid CSRF token)')
werkzeug.exceptions.BadRequest: 400 Bad Request: Session expired (invalid CSRF token)

Then my question is (because I don't have access nor I want to disable the CSRF token). How to declare one with AJAX ?

Thank you for reading, I hope we can find the solution together.

P.S.: I saw this one (https://stackoverflow.com/a/41486127/13147732) but I'm not sure about security. Maybe this one can help (https://stackoverflow.com/a/53151896/13147732).


Solution

  • Good afternoon everyone,

    For this problem, I didn't find the way to declare this CSRF Token but there's a workaround.

    We can use the form version to add to the wishlist. Why, because when adding to the wishlist there aren't a redirection (instead of the Add To Cart).

    In my case I don't have any code to show to you because we choose to not use the wishlist. If you want an example, you can see how to make it in your own website on any add to wishlist button.