web-dev-qa-db-fra.com

wp_verify_nonce renvoie toujours la valeur false lorsqu'il est connecté en tant qu'administrateur

J'ai implémenté certaines fonctionnalités AJAX pour mon plugin et cela fonctionne correctement tant que je ne suis pas connecté en tant qu'administrateur - alors wp_verify_nonce échoue. Cela fonctionne pour les utilisateurs non autorisés et les utilisateurs réguliers autorisés.

Voici ma classe PHP (j'ai supprimé tout ce qui ne concerne pas le problème):

class My_Ajax {
    function __construct() {
        add_action( 'wp_ajax_geoip_citylist', array($this, 'geoip_citylist') );
        add_action( 'wp_ajax_nopriv_geoip_citylist', array($this, 'geoip_citylist') );
        add_action( 'wp_enqueue_scripts', array($this, 'geoip_localize_js'), 11 );
    }

    function geoip_citylist() {
        if ( ! wp_verify_nonce($_POST['geoipNonce'], 'my_geoip_nonce') ) {
            exit('Wrong nonce: ' . $_POST['geoipNonce']);
        }
    }


    function geoip_localize_js() {
        wp_localize_script(
            'my_custom_js', 'myGeoipAjaxObject', 
            array( 
                'myGeoipNonce' => wp_create_nonce('my_geoip_nonce')
            ) 
        );
    }
}

Et voici mon Javascript:

$.ajax({
    url: myMainAjaxObject.ajaxUrl,
    type: 'POST',
    dataType: 'json',
    data: {
        geoipNonce: myGeoipAjaxObject.myGeoipNonce,
        action: "geoip_citylist"
    },
    success: function(data) {
        replacePhones(data.user_city, data.current_phone, data.city_list);
    },
    error: function(error) {
        console.log(error);
    }
});

La réponse d'erreur nonce dans PHP semble être correcte, mais elle n'est toujours pas validée pour une raison quelconque.

J'ai passé des jours à essayer de comprendre ce qui n'allait pas et à essayer de le rechercher de toutes les manières possibles, mais je ne pouvais pas trouver de solution qui fonctionnerait. Il y a des questions sans réponse avec des problèmes similaires sur stackoverflow, comme celui-ci qui a été créé en 2011 ... Je peux simplement supposer que les nonces ne fonctionnent pas avec comptes d’administrateur dans Wordpress, mais j’aimerais au moins obtenir une confirmation avant d’abandonner.

UPDATE: J'ai essayé d'utiliser uniquement le code que j'ai fourni ici et cela a toujours entraîné la même erreur (j'ai également vérifié le cache et il a été actualisé).

UPDATE 2: myMainAjaxObject et sa ajaxUrl sont insérés dans un autre script. Puisque l'URL AJAX est identique pour chaque demande AJAX, j'utilise simplement la requête globale au lieu de la redéfinir à chaque fois. Donc, ce n'est pas ce qui cause l'erreur. De plus, si cela n'était pas défini, cela ne fonctionnerait jamais. Encore une fois, cela ne fonctionne pas uniquement pour l'administrateur, pour les autres utilisateurs et les utilisateurs non autorisés, cela fonctionne bien. Et je reçois le message "Wrong nonce: 73dd02f662" dans la réponse du serveur lorsque je suis connecté en tant qu'administrateur. Donc, je suis sûr à 100% que cette URL est correcte.

1
Dmitriy Gamolin

Je pense que le problème était que j'ai supprimé manuellement mes cookies plusieurs fois lors des tests. Parmi eux se trouvait un cookie appelé "wordpress_logged_in_ {token}", où {token} est un identifiant unique. Ma meilleure hypothèse est que l'absence de ce cookie a posé des problèmes de création et/ou de vérification de non-respect. C’était difficile à remarquer car j’étais encore capable de naviguer dans le panneau d’administration (il semble que WP utilise un cookie différent appelé "wordpress_ {token}") et ce site Web ne montrer le statut de l'utilisateur n'importe où (les comptes n'y sont pas utilisés, mais la fonctionnalité de connexion est là, juste cachée de la vue).

La solution était très simple: je me suis connecté à nouveau en tant qu'administrateur et mon AJAX a également commencé à fonctionner pour cet administrateur. Donc, si quelqu'un rencontre un problème similaire, assurez-vous que lorsque vous supprimez les cookies, vous ne supprimez que ceux dont vous avez besoin de supprimer/régénérer ou, si vous les supprimez tous comme je l'ai fait, veillez à vous connecter à nouveau en tant qu'administrateur.

PS: Je suis désolé de ne pas avoir fourni tous les détails du début, mais j’ai essayé de fournir autant d’informations que nécessaire. Je savais qu'il me manquait quelque chose et maintenant je me sens stupide d'avoir posé cette question. Cependant, je ne vais pas le supprimer pour que peut-être quelqu'un qui se heurte au même problème puisse gagner du temps.

6
Dmitriy Gamolin

Ajax URL dans WordPress est quelque chose comme ceci https://examle.com/wp-admin/admin-ajax.php. Lorsque vous n'êtes pas connecté et que vous êtes dans l'interface, vous devez transmettre l'URL au script.

Dans votre code, vous utilisez ceci:

url: myMainAjaxObject.ajaxUrl,

mais myMainAjaxObject.ajaxUrl n'est pas défini. Vous pouvez le faire comme ceci:

wp_localize_script(
    'my_custom_js', 'myGeoipAjaxObject', 
    array( 
        'myGeoipNonce' => wp_create_nonce('my_geoip_nonce'),
        'ajaxUrl'      => admin_url( 'admin-ajax.php' )
    )
);

Maintenant, vous pouvez utiliser myMainAjaxObject.ajaxUrl dans le frontend et pour les utilisateurs non connectés.

2
cybmeta