admin管理员组文章数量:1279042
I built a plugin, but now on end, I am not sure whether my nonce
integrated correctly, and I'm not sure how to test them.
Can anyone help me test it or let me know if the nonce
is integrated correctly?
Here is one example from my code:
PHP:
public function __construct() {
if ( ! is_admin() ) {
add_action( 'wp_head', array( $this, 'pp_html_template' ) );
add_action( 'init', array( $this, 'pp_html_process' ) );
}
add_action( 'wp_ajax_pp_html_process', array( $this, 'pp_html_process' ) );
}
public function pp_html_template() {
?>
<form id="pp-form-submit" name="pp-form-submit" class="pp-form-submit" enctype="multipart/form-data">
<?php wp_nonce_field( 'pp_publisher_save', 'pp_publisher_name' ); ?>
<div class="pp-row">
<label for="pp-title"><?php esc_attr_e( 'Title', 'post-publisher' ) ?></label>
<input type="text" id="pp-title" name="pp_title" required>
</div>
<div class="pp-row">
<label for="pp-content"><?php esc_attr_e( 'Content', 'post-publisher' ) ?></label>
<textarea id="pp-content" name="pp_content" cols="30" rows="10" required></textarea>
</div>
<div class="pp-row">
<label for="pp-featured-image"><?php esc_attr_e( 'Featured Image', 'post-publisher' ) ?></label>
<input type="file" id="pp-featured-image" name="pp_featured_image" required>
</div>
<input type="hidden" name="action" value="pp_html_process"/>
<div class="pp-row">
<input type="submit" name="pp_submit" id="pp-submit">
</div>
<div class="pp-row">
<div id="pp-response"></div>
<div class="pp-posts-area"></div>
</div>
</form>
<?php }
public function pp_html_process() {
if ( isset( $_POST['pp_submit'] ) ) {
if ( ! isset( $_POST['pp_publisher_name'] ) || ! wp_verify_nonce( $_POST['pp_publisher_name'], 'pp_publisher_save' ) ) {
esc_attr__( 'Sorry, this action is not allowed.', 'post-publisher' );
exit;
} else {
$inc = new Pp_Includes();
$inc->pp_post_data('pp_title', 'pp_content', 'pp_featured_image');
global $current_user;
$user_login = $current_user->user_login;
$user_id = $current_user->ID;
$post_title = sanitize_text_field( $_POST[ 'pp_title' ] );
$post_content = sanitize_textarea_field( $_POST[ 'pp_content' ] );
$arg = array(
'post_title' => $post_title,
'post_content' => $post_content,
'post_author' => $user_id,
'post_type' => 'post',
'post_status' => 'draft',
'post_name' => str_replace( ' ', '-', $post_title ),
);
$post_id = wp_insert_post( $arg, true );
if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) {
require_once( ABSPATH . "wp-admin" . '/includes/image.php' );
require_once( ABSPATH . "wp-admin" . '/includes/file.php' );
require_once( ABSPATH . "wp-admin" . '/includes/media.php' );
}
$featured_image = media_handle_upload( 'pp_featured_image', $post_id );
if ( is_wp_error( $featured_image ) ) {
wp_die( $featured_image );
}
if ( $featured_image > 0 ) {
update_post_meta( $post_id, '_thumbnail_id', $featured_image );
}
if ( wp_doing_ajax() ) {
wp_die();
}
}
}
}
Here is the localized script:
public function pp_enqueue_public_styles() {
wp_enqueue_script( 'pp_public_ajax', plugins_url( '/assets/js/pp-public-ajax.js', __FILE__ ), array( 'jquery' ), null, true );
wp_localize_script( 'pp_public_ajax', 'pp_public_ajax',
array(
'pp_ajaxurl' => admin_url( 'admin-ajax.php' ),
'pp_publisher_name' => wp_create_nonce( 'pp_publisher_save' )
)
);
}
AJAX:
function ppAjaxSubmit() {
var ppFormData = new FormData(this);
ppFormData.append('pp_submit', 1);
ppFormData.append('security', pp_public_ajax.pp_publisher_name)
$.ajax({
action: 'pp_featured_image',
type: 'POST',
url: pp_public_ajax.pp_ajaxurl,
data: ppFormData,
processData: false,
contentType: false,
success: function () {
console.log(data);
},
error: function () {
console.log(err)
}
});
return false;
}
$('#pp-form-submit').submit(ppAjaxSubmit);
Any advice would be appreciated.
I built a plugin, but now on end, I am not sure whether my nonce
integrated correctly, and I'm not sure how to test them.
Can anyone help me test it or let me know if the nonce
is integrated correctly?
Here is one example from my code:
PHP:
public function __construct() {
if ( ! is_admin() ) {
add_action( 'wp_head', array( $this, 'pp_html_template' ) );
add_action( 'init', array( $this, 'pp_html_process' ) );
}
add_action( 'wp_ajax_pp_html_process', array( $this, 'pp_html_process' ) );
}
public function pp_html_template() {
?>
<form id="pp-form-submit" name="pp-form-submit" class="pp-form-submit" enctype="multipart/form-data">
<?php wp_nonce_field( 'pp_publisher_save', 'pp_publisher_name' ); ?>
<div class="pp-row">
<label for="pp-title"><?php esc_attr_e( 'Title', 'post-publisher' ) ?></label>
<input type="text" id="pp-title" name="pp_title" required>
</div>
<div class="pp-row">
<label for="pp-content"><?php esc_attr_e( 'Content', 'post-publisher' ) ?></label>
<textarea id="pp-content" name="pp_content" cols="30" rows="10" required></textarea>
</div>
<div class="pp-row">
<label for="pp-featured-image"><?php esc_attr_e( 'Featured Image', 'post-publisher' ) ?></label>
<input type="file" id="pp-featured-image" name="pp_featured_image" required>
</div>
<input type="hidden" name="action" value="pp_html_process"/>
<div class="pp-row">
<input type="submit" name="pp_submit" id="pp-submit">
</div>
<div class="pp-row">
<div id="pp-response"></div>
<div class="pp-posts-area"></div>
</div>
</form>
<?php }
public function pp_html_process() {
if ( isset( $_POST['pp_submit'] ) ) {
if ( ! isset( $_POST['pp_publisher_name'] ) || ! wp_verify_nonce( $_POST['pp_publisher_name'], 'pp_publisher_save' ) ) {
esc_attr__( 'Sorry, this action is not allowed.', 'post-publisher' );
exit;
} else {
$inc = new Pp_Includes();
$inc->pp_post_data('pp_title', 'pp_content', 'pp_featured_image');
global $current_user;
$user_login = $current_user->user_login;
$user_id = $current_user->ID;
$post_title = sanitize_text_field( $_POST[ 'pp_title' ] );
$post_content = sanitize_textarea_field( $_POST[ 'pp_content' ] );
$arg = array(
'post_title' => $post_title,
'post_content' => $post_content,
'post_author' => $user_id,
'post_type' => 'post',
'post_status' => 'draft',
'post_name' => str_replace( ' ', '-', $post_title ),
);
$post_id = wp_insert_post( $arg, true );
if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) {
require_once( ABSPATH . "wp-admin" . '/includes/image.php' );
require_once( ABSPATH . "wp-admin" . '/includes/file.php' );
require_once( ABSPATH . "wp-admin" . '/includes/media.php' );
}
$featured_image = media_handle_upload( 'pp_featured_image', $post_id );
if ( is_wp_error( $featured_image ) ) {
wp_die( $featured_image );
}
if ( $featured_image > 0 ) {
update_post_meta( $post_id, '_thumbnail_id', $featured_image );
}
if ( wp_doing_ajax() ) {
wp_die();
}
}
}
}
Here is the localized script:
public function pp_enqueue_public_styles() {
wp_enqueue_script( 'pp_public_ajax', plugins_url( '/assets/js/pp-public-ajax.js', __FILE__ ), array( 'jquery' ), null, true );
wp_localize_script( 'pp_public_ajax', 'pp_public_ajax',
array(
'pp_ajaxurl' => admin_url( 'admin-ajax.php' ),
'pp_publisher_name' => wp_create_nonce( 'pp_publisher_save' )
)
);
}
AJAX:
function ppAjaxSubmit() {
var ppFormData = new FormData(this);
ppFormData.append('pp_submit', 1);
ppFormData.append('security', pp_public_ajax.pp_publisher_name)
$.ajax({
action: 'pp_featured_image',
type: 'POST',
url: pp_public_ajax.pp_ajaxurl,
data: ppFormData,
processData: false,
contentType: false,
success: function () {
console.log(data);
},
error: function () {
console.log(err)
}
});
return false;
}
$('#pp-form-submit').submit(ppAjaxSubmit);
Any advice would be appreciated.
Share Improve this question edited Sep 28, 2021 at 15:40 upss1988 asked Sep 28, 2021 at 13:25 upss1988upss1988 178 bronze badges 8- note that this won't run for logged out users, but I'm curious, is there a reason you chose the old legacy admin AJAX to handle your JS requests instead of a modern REST API route? – Tom J Nowell ♦ Commented Sep 28, 2021 at 14:07
- @TomJNowell I'm aware that it's working only with the logged-in user. I'm not entirely familiar with the REST API route, so that is why this way. Any feedback on my question, maybe? – upss1988 Commented Sep 28, 2021 at 14:20
- A REST API route would handle the nonce for you out of the box as part of the authentication process, and provide parameters letting you pass it functions that deal directly with what you're asking about. The REST API does a lot of things for you that admin AJAX forces you to build yourself ( e.g. validating nonces ) – Tom J Nowell ♦ Commented Sep 28, 2021 at 14:27
- @TomJNowell Ok, thank you. – upss1988 Commented Sep 28, 2021 at 14:28
- Also remember these are comments, nobody has written a solution to your question yet. As this isn't a discussion forum, you need a question that's specific enough that someone can give a concrete objective factual answer that thoroughly answers it, not just an opinion or comment. That's why I left a comment instead of an answer. – Tom J Nowell ♦ Commented Sep 28, 2021 at 14:30
1 Answer
Reset to default 1I see some issues:
- You ajax action can be only used by logged users. If this is correct, I recommend you add a nopriv action that returns a error message.
// Inside Constructor
add_action( 'wp_ajax_nopriv_pp_html_process', array( $this, 'pp_html_process_not_logged' ) );
And create this function :
public function pp_html_process_not_logged () {
// Status can be used to identify via JS if the operation is OK or KO and print an error with jQuery or a modal window, whatever you prefer.
wp_send_json([
'status' => false,
'error' => __('Error. This service is only for logged users.', 'your_plugin_lang_slug')
]);
}
- You create a wp_nonce field that will not be used (later in JS you are creating other with the same name / action). Remove this line in your "pp_html_template" function:
<?php wp_nonce_field( 'pp_publisher_save', 'pp_publisher_name' ); ?>
wp_head prints your HTML inside the HEAD tag and that's is not "allowed". This form needs to be inside BODY tag. Maybe you can add it in footer or a better solution is create a shortcode with add_shortcode function and put the shortcode in pages or post you want to display this form.
Remove this lines in your constructor because reason explained in 3 and because you are creating an AJAX action and ajax actions are processed by wp_ajax_{$action} hook.
if ( ! is_admin() ) {
add_action( 'wp_head', array( $this, 'pp_html_template' ) );
add_action( 'init', array( $this, 'pp_html_process' ) );
}
Ensure "pp_enqueue_public_styles" is called in "wp_enqueue_scripts" or "admin_enqueue_scripts" if it only appears on Dashboard. If you decide to create a shortcode, you can call this function before form.
In your JS file change this lines:
ppFormData.append('pp_submit', 1);
ppFormData.append('security', window.pp_public_ajax.pp_publisher_name)
ppFormData.append('action', 'pp_html_process');
And remove this line inside AJAX function:
action: 'pp_featured_image',
- You have an error in your "pp_enqueue_public_styles" function:
public function pp_enqueue_public_styles() {
// Register the script first!!
wp_register_script( 'pp_public_ajax', plugins_url( '/assets/js/pp-public-ajax.js', __FILE__ ), array( 'jquery' ), null, true );
wp_localize_script( 'pp_public_ajax', 'pp_public_ajax',
array(
'pp_ajaxurl' => admin_url( 'admin-ajax.php' ),
'pp_publisher_name' => wp_create_nonce( 'pp_publisher_save' )
)
);
wp_enqueue_script('pp_public_ajax');
}
本文标签: phpHow to test nonce with AJAXPlugin development
版权声明:本文标题:php - How to test nonce with AJAX - Plugin development 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741293651a2370692.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论