Wordpress verify_nonce не работает, когда не залогинен - PullRequest
0 голосов
/ 31 марта 2019

Я создаю собственную тему Wordpress с формой входа для посетителей моего сайта. Форма имеет поле для имени пользователя, пароля, скрытого одноразового поля и скрытого поля действия. При отправке форма отправляет wp-admin/admin-post.php, в которую я подключаю пользовательскую функцию для обработки входа в систему.

Если я просто беру имя пользователя и пароль в пользовательской функции входа в систему и подключаю их к wp_signon(), все работает отлично, и пользователь может войти в систему. Однако, если я пытаюсь проверить одноразовый номер, используя wp_verify_nonce($nonce,$action), это возвращает ложь. Я создал одноразовый номер, используя wp_create_nonce($action). Я проверил, что одноразовый номер, полученный функцией входа в переменную $ _POST, совпадает с созданным мной одноразовым номером, и действие, которое я подключаю к функции проверки, также совпадает с действием, которое я подключаю к созданию. функция.

У меня также есть функция выхода из системы, к которой обращается запрос get на mydomain/wp-admin/admin-post.php?action=action&nonce=nonce. В пользовательской функции выхода из системы, которая обрабатывает этот запрос, я проверяю одноразовый номер точно таким же образом, но здесь он работает нормально. Есть ли что-то, что мне нужно сделать по-другому, чтобы создать одноразовые номера, когда пользователь еще не вошел в систему? Я думал, что одноразовый номер был основан на хэше userID и некоторой информации о времени, но, поскольку идентификатор пользователя равен 0 (не зарегистрирован) как при создании, так и при проверке одноразового номера, я не понимаю, почему это не сработает.

для справки, пользовательская функция входа в систему в functions.php. Оператор echo возвращает правильный одноразовый номер, но $nonceResult является ложным.

function handle_customer_login() {
    $username = $_POST['username'];
    $password = $_POST['password'];
    $nonce = $_POST['_nonce'];
    $nonceResult = wp_verify_nonce($nonce,'customer_login');

    if (empty($_POST['_nonce'])) {
        echo 'error: ';
        var_dump($nonceResult);
        die();
    } else {
        echo 'nonce: '.$_POST['_nonce'];
        var_dump($nonceResult);
        die();
    }
}
add_action('admin_post_customer_login','handle_customer_login'); 
add_action('admin_post_nopriv_customer_login','handle_customer_login'); 

Я создаю одноразовый номер в строке кода ниже и добавляю $login_nonce к функции wp_localize_script(), чтобы передать его в javascript. Затем я отрисовываю форму входа в систему с помощью javascript, в котором одноразовый номер прекрасно отображается внутри скрытого поля.

$login_nonce = wp_create_nonce('customer_login');

1 Ответ

1 голос
/ 01 апреля 2019

Я нашел решение сам.Может быть, это кому-нибудь поможет.Я заглянул внутрь функции, которая создает одноразовый номер и проверяет его.Оба принимают некоторые переменные (одноразовый тик, идентификатор пользователя, токен сеанса, действие) и создают хэш, последние индексы которого становятся одноразовыми.Если вы проверяете одноразовый номер, предоставленный запросом, одноразовый номер воссоздается на основе этих входных переменных, и если он совпадает, он действителен.

Если зарегистрированный пользователь отсутствует, создается поддельный идентификатор пользователя на основе фильтрации идентификатора пользователя и действия с фильтром nonce_user_logged_out (apply_filters( 'nonce_user_logged_out', $uid, $action );).Я проверил, какие функции подключены к этому шагу фильтра как во время создания, так и при проверке.Оказалось, что во время проверки не было подключено ни одной функции, но nonce_user_logged_out было подключено во время создания.Я смог решить эту проблему, добавив фильтр nonce_user_logged_out, используя add_filter(), перед запуском wp_verify_nonce.

...