I am trying to update the user password through a ‘form’, everything works correctly. However, if I try to update the password again without reloading the page, the nonce verification fails and I can’t understand why. I have tried regenerating the nonce but it doesn’t solve the problem. The only thing that allows the nonce verification to pass for subsequent requests is refreshing the tab of my plugin or the entire page, but the goal here is to update the user data without reloading the page.
The first request is successful and the page is updated but subsequent ones fail:
// 1. nonce verification
if ( ! isset($_POST['security_nonce']) || ! wp_verify_nonce( $_POST['security_nonce'], 'update_user_security_nonce' ) ) {
// Nonce invalido, mostra un messaggio d'errore
$error_message = $this->get_message_html('error', 'Nonce Verification Failed');
wp_send_json_error(array('message' => $error_message));
return;
}
P.S: My form is dynamically loaded with an ajax request because it is located within a specific tab of my plugin.
Handle_User_Form.php
// Handle Ajax Request server side
public function update_security_password() {
// Password Var...
$current_password = sanitize_text_field($_POST['current_password']);
$new_password = sanitize_text_field($_POST['new_password']);
$confirm_password = sanitize_text_field($_POST['confirm_password']);
$passwordRegex = '/^(?=.*[a-z])(?=.*[A-Z])(?=.*d)(?=.*[@$!%*#?&])[A-Za-zd@$!%*#?&]{8,}$/';
// 1. nonce verification
if ( ! isset($_POST['security_nonce']) || ! wp_verify_nonce( $_POST['security_nonce'], 'update_user_security_nonce' ) ) {
// Nonce invalido, mostra un messaggio d'errore
$error_message = $this->get_message_html('error', 'Nonce Verification Failed');
wp_send_json_error(array('message' => $error_message));
return;
}
// 2. other verification
if (empty($current_password)) {
$error_message = $this->get_message_html('error', 'msg error');
wp_send_json_error(array('message' => $error_message));
return;
}
// 3. other verification
if (empty($new_password)) {
$error_message = $this->get_message_html('error', 'msg error');
wp_send_json_error(array('message' => $error_message));
return;
}
// 4. other verification
if (!empty($current_password)) {
$user = get_user_by('id', get_current_user_id());
// Se la password attuale è corretta procedi con i controlli sottostanti
if ($user && wp_check_password($current_password, $user->data->user_pass, $user->ID)) {
// Se new_password è diversa da confirm_password mostra un msg d'errore
if ($new_password !== $confirm_password) {
$error_message = $this->get_message_html('error', 'msg error');
wp_send_json_error(array('message' => $error_message));
return;
}
// other verification
if ($new_password === $current_password) {
$error_message = $this->get_message_html('error', 'msg error.');
wp_send_json_error(array('message' => $error_message));
return;
}
// regex verification
if (!empty($new_password) && !preg_match($passwordRegex, $new_password)) {
$error_message = $this->get_message_html('error', 'msg error.');
wp_send_json_error(array('message' => $error_message));
return;
}
} else {
$error_message = $this->get_message_html('error', 'msg error.');
wp_send_json_error(array('message' => $error_message));
}
}
// Array with new data
$userdata = array(
'ID' => get_current_user_id(),
);
// Update Data
$user_id = wp_update_user( $userdata );
// Update correctly
if ( !is_wp_error( $user_id ) ) {
// Restituisci un messaggio di successo
wp_send_json_success( array(
'message' => $this->get_message_html('success', 'Updated.')));
} else {
// If update fail
wp_send_json_error( array('message' => $this->get_message_html('error', $user_id->get_error_message())));
}
}
User_Form.js
jQuery(document).ready(function($) {
$(document).on('click', '#update_password_btn', function() {
var current_password = $('#current_password').val();
var new_password = $('#new_password').val();
var confirm_password = $('#confirm_password').val();
var security_nonce = $('#security_nonce').val();
// Data Object
var data = {
action: 'update_security_password', // Sostituisci con l'azione corretta
current_password: current_password,
new_password: new_password,
confirm_password: confirm_password,
security_nonce: security_nonce,
};
// Ajax Request
$.ajax({
url: adminAjax.ajax_url,
type: 'POST',
dataType: 'json',
data: data,
success: function(response) {
// Controlla se la risposta ha successo.
if (response.success) {
// Success Message
$('#info_message').attr('class', 'success').html(response.data.message).show();
// Clear Password Field
$('#current_password').val('');
$('#new_password').val('');
$('#confirm_password').val('');
} else {
// Error Message
$('#info_message').attr('class', 'error').html(response.data.message).show();
vibrate(document.getElementById('info_message'));
}
},
error: function(xhr, textStatus, errorThrown) {
// Handle Other Error
console.error('Errore AJAX:', textStatus, errorThrown);
$('#info_message').attr('class', 'error').html('Errore nella richiesta, riprova.').show();
}
});
});
});
Template_User_Form.php
<!-- Dati D'accesso -->
<div class="wrap_form_block">
<!-- Campo Nonce -->
<input type="hidden" id="security_nonce" name="security_nonce" value="<?php echo wp_create_nonce('update_user_security_nonce'); ?>">
<!-- Update Password Section -->
<div class="wrap_form_block password">
<!-- Campi per la modifica della password -->
<div class="container_form_fields">
<div class="form_fields">
<label for="current_password">Current Attuale</label>
<div class="wrap-input">
<input class="password-input" id="current_password" type="password" name="current_password" />
<span class="toggle-password fa-light fa-eye"></span>
</div>
</div>
<div class="form_fields">
<label for="new_password">New Password</label>
<div class="wrap-input">
<input class="password-input" id="new_password" type="password" name="new_password" />
<span class="toggle-password fa-light fa-eye"></span>
</div>
<div id="password-strength"></div>
</div>
<div class="form_fields">
<label for="confirm_password">Confirm Password</label>
<div class="wrap-input">
<input class="password-input" id="confirm_password" type="password" name="confirm_password" />
<span class="toggle-password fa-light fa-eye"></span>
</div>
</div>
</div>
<!-- Update Button -->
<div class="wrap_form_button">
<button class="btn_m button_blue" type="button" id="update_password_btn">Salva Modifica Password</button>
</div>
</div>