wp verify nonce всегда возвращает значение false при входе в систему от имени администратора


Я реализовал некоторые функции AJAX для своего плагина, и он работает нормально, пока я не вошел в систему как администратор - тогда wp_verify_nonce не удается. Он работает как для неавторизованных пользователей, так и для авторизованных обычных пользователей.

Вот мой класс PHP (я удалил все, что не имеет отношения к проблеме):

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')
            ) 
        );
    }
}

И вот мой 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);
    }
});

Ответ на ошибку PHP, по-видимому, правильный, но по какой-то причине он все еще не проверяется.

Я потратил несколько дней, пытаясь понять, что не так, и пытаясь погуглить это всеми возможными способами, но до сих пор я не мог найти решение, которое бы сработало. Есть вопросы без ответа с аналогичными проблемами в stackoverflow, такие как этот, который был создан в 2011 году... Я мог бы просто предположить, что nonces не работают с учетными записями администраторов в Wordpress, но я хотел бы, по крайней мере, получить подтверждение, прежде чем сдаваться.

ОБНОВЛЕНИЕ: Я пытался использовать только тот код, который я предоставил здесь и это все равно привело к той же ошибке (я также дважды проверил кэш, и он был обновлен).

ОБНОВЛЕНИЕ 2: myMainAjaxObject и его ajaxUrl вставляются в другой скрипт. Поскольку URL-адрес AJAX одинаков для каждого запроса AJAX, я просто использую глобальный, а не каждый раз переопределяю его. Так что это не то, что вызывает ошибку. Кроме того, если бы это не было определено, это никогда бы не сработало. Еще раз, это работает не только для администратора, для других пользователей и неавторизованных пользователей это работает нормально. И я получите "Неправильный nonce: 73dd02f662" в ответе сервера, когда я войду в систему как администратор. Поэтому я на 100% уверен, что URL-адрес правильный.

Author: Community, 2016-10-07

2 answers

Я думаю, что проблема заключалась в том, что я несколько раз вручную удалял свои файлы cookie во время тестирования. Среди них был файл cookie под названием "wordpress_logged_in_{токен}", где {токен} является уникальным идентификатором. Мое лучшее предположение заключается в том, что отсутствие этого файла cookie вызвало проблемы с созданием или/и проверкой nonce. Это было трудно заметить, потому что я все еще мог просматривать панель администратора (похоже, что WP использует другой файл cookie под названием "wordpress_{токен}"), и на передней панели этот веб-сайт не отображается статус пользователя в любом месте (учетные записи там не используются, однако функция входа в систему есть, просто скрыта от просмотра).

Решение было очень простым - я просто повторно вошел в систему как администратор, и мой AJAX также начал работать на администратора. Поэтому, если кто-то столкнется с подобной проблемой, убедитесь, что при очистке файлов cookie вы либо удаляете только те, которые вам нужно удалить/восстановить, либо, если вы удаляете их все, как я, обязательно повторно войдите в систему как администратор.

PS: Мне жаль, что я не предоставил все подробности с самого начала, но я постарался предоставить столько информации, сколько необходимо. Я знал, что мне чего-то не хватает, и теперь чувствую себя глупо, даже задавая этот вопрос. Тем не менее, я не собираюсь удалять его, чтобы, возможно, кто-то, кто столкнется с такой же проблемой, мог сэкономить некоторое время.

 7
Author: Dmitriy Gamolin, 2016-10-09 09:53:16

URL-адрес Ajax в WordPress выглядит примерно так https://examle.com/wp-admin/admin-ajax.php. Когда вы не вошли в систему и находитесь во внешнем интерфейсе, вам нужно передать URL-адрес скрипту.

В своем коде вы используете следующее:

url: myMainAjaxObject.ajaxUrl,

Но myMainAjaxObject.ajaxUrl не определено. Вы могли бы сделать это так:

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

Теперь вы можете использовать myMainAjaxObject.ajaxUrl во внешнем интерфейсе и для пользователей, не вошедших в систему.

 2
Author: cybmeta, 2016-10-07 09:10:48