WordPress nonce no verifica la acción del carrito de WooCommerce

3 minutos de lectura

Creé un carrito de WooCommerce personalizado donde puede cambiar cantidades y/o eliminar elementos de su carrito con AJAX, pero tiene errores y creo que tiene algo que ver con WooCommerce y la validez de los nonces de WordPress.

El problema:

Funciona cuando hay un producto en su carrito y actualizó la página al menos una vez, después de agregar el producto a su carrito.

no funciona cuando es su primera visita, agrega un producto en su carrito e intenta editar las cantidades del producto, o intenta eliminarlo.

Compruébelo usted mismo en https://staging.noten.nl/noten/ – verifique en su teléfono inteligente por favor. Agregue un producto al carrito, haga clic en él y cambie los valores (250 g más / 250 g menos / eliminar producto)

PHP – Creación de nonce

/*
**  Theme scripts
*/
function scripts() {

    // Enqueue scripts
    wp_enqueue_script( 'noten-nl/js', Assets\asset_path('scripts/main.js?v=' . VERSION), ['jquery-core', 'wp-util'], null, true );

    // Localize script
    wp_localize_script( 'noten-nl/js', 'shop', array(
        'url'           => admin_url( 'admin-ajax.php' ),
        'cart_more'     => wp_create_nonce( 'cart-more-nonce' ),
        'cart_less'     => wp_create_nonce( 'cart-less-nonce' ),
        'cart_delete'   => wp_create_nonce( 'cart-delete-nonce' )
    ));

}
add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\\scripts', 999 );

Javascript (llama a la función PHP cart_more a continuación)

/*
**  Edit items in cart
*/
function cartAction(event) {

    // Log
    console.log('cartAction');

    // Variables
    var action = $(event.currentTarget).attr('data-action'),
        product = $('.cart-products-scroll .row.active');

    // Load
    product.children('.cart-row-item-loading').show();

    // AJAX
    wp.ajax.send('cart_' + action, {
        data: {
            nonce:      shop['cart_' + action],
            id:         product.attr('data-product-id'),
            quantity:   product.attr('data-product-quantity'),
            key:        product.attr('data-product-cart-item-key')
        },
        success: function (fragments) {

            // Replace fragments
            $.each(fragments, function (key, value) {
                $(key).replaceWith(value);
            });

        },
        error: function (response) {
            console.log(response);
        }
    });

}

PHP

function cart_more() {

    // Log
    write_log( 'cart_more()' );

    // Variables
    $nonce = isset( $_POST['nonce'] ) ? $_POST['nonce'] : '';
    $product_id = isset( $_POST['id'] ) ? $_POST['id'] : '';
    $product_quantity = isset( $_POST['quantity'] ) ? $_POST['quantity'] : '';

    // Check data
    if ( wp_verify_nonce( $nonce, 'cart-more-nonce' ) && ! empty( $product_id ) && ! empty( $product_quantity ) ) {

        /*
        ** Removed for readability
        */

        // Send success
        wp_send_json_success( $fragments );

    } else {

        // Send error
        wp_send_json_error( ':\'(' );

    }

}
add_action( 'wp_ajax_nopriv_cart_more', __NAMESPACE__ . '\\cart_more' );
add_action( 'wp_ajax_cart_more', __NAMESPACE__ . '\\cart_more' );

Pregunta

¿Por qué la verificación nonce solo tiene éxito después de agregar algo a mi carrito?

  • ¿Conseguiste solucionar este problema? yo tengo el mismo ahora mismo

    usuario1133297

    22 de junio de 2017 a las 14:23

Para hacer que las páginas de productos se puedan almacenar en caché, las sesiones de WooCommerce no se crean hasta que se crea un carrito.1,2

WooCommerce anula uno de los parámetros nonce con un valor que cambia en función de si se ha creado o no una sesión de WooCommerce.3,4

Cuando crea el nonce para un nuevo usuario sin carrito ni sesión, el nonce se calcula con un conjunto de entradas. Cuando verifica el nonce después de agregar un artículo al carrito, el valor de verificación se genera con un conjunto diferente de entradas porque la sesión de WooCommerce ahora existe. Esto hace que se genere un valor de nonce diferente y que falle la comprobación de nonce con el valor de nonce antiguo.

Una solución es crear proactivamente la sesión de WooCommerce antes de crear los nonces. Tenga en cuenta que esto podría afectar la forma en que se almacena en caché su sitio.

  1. https://github.com/woocommerce/woocommerce/issues/4920#issuecomment-35846419
  2. https://mikejolley.com/2013/12/20/problems-with-cart-sessions-and-woocommerce/
  3. https://developer.wordpress.org/reference/functions/wp_create_nonce/
  4. https://github.com/woocommerce/woocommerce/blob/c16acc6b5104acb0ed082e7df1c63dfd77598459/includes/class-wc-session-handler.php#L224

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad