Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk10 min

How to Use Nonces in WordPress: Forms, AJAX, REST, and Security

A practical guide to WordPress nonces: create action-specific tokens, verify them correctly for forms, AJAX, and REST, and understand why a nonce never replaces authentication or capability checks.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use an action-specific WordPress nonce to reduce CSRF risk on a state-changing request, verify it in the context that received it, and still enforce permissions with a capability check. A nonce confirms that WordPress generated the page or script; it does not authenticate the requester or authorize the operation.

What a WordPress nonce does

WordPress uses the term “nonce” for a hash-based value that helps protect forms, URLs, AJAX calls, and cookie-authenticated REST requests from cross-site request forgery (CSRF). The name comes from “number used once,” but a WordPress nonce is not necessarily numeric and is not single-use. It remains valid for a time window and can normally be submitted more than once during that window.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The useful question is whether the request came from a page or script that WordPress generated for the current user and action. That is different from asking who the user is or whether the user may perform the operation. Authentication, authorization, and input validation remain separate controls.

Choose an action string first

Every nonce should be tied to a precise action. Use a context-rich value such as delete-comment_123, not a generic string such as save or my-plugin. Include the operation and, where practical, the object identifier or other context that distinguishes one dangerous action from another.

  • Specific: delete-comment_123 identifies deletion of comment 123.
  • Stable: use exactly the same action when creating and verifying the token.
  • Scoped: do not reuse a token intended for one operation on unrelated operations.

An action string is not a permission. A user who presents a valid token can still fail the capability check for the target resource.

Creating nonces for forms

Use wp_nonce_field() inside a form

For an HTML form, call wp_nonce_field() while rendering the form. It prints hidden fields containing the nonce and its field name, allowing the submitted request to carry the value back to WordPress.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<form method='post' action='<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>'>
    <input type='hidden' name='action' value='delete_comment'>
    <input type='hidden' name='comment_id' value='<?php echo esc_attr( $comment_id ); ?>'>
    <?php wp_nonce_field( 'delete-comment_' . $comment_id ); ?>
    <button type='submit'>Delete comment</button>
</form>

The action passed to wp_nonce_field() must match the action used during verification. Escape any separately rendered IDs and values as appropriate for their output context; the nonce does not sanitize the rest of the form.

When a custom field name is useful

The function can use a custom nonce field name when your handler expects one. If you change the name, pass that same name to the verification function or read it deliberately in custom handling. Keeping the default field name is usually simplest and makes WordPress conventions easier to recognize.

Creating nonces for links and URLs

Use wp_nonce_url() for a nonce-bearing URL

For a link that triggers a state-changing action, pass the destination URL and action to wp_nonce_url(). WordPress adds a nonce query parameter, normally named _wpnonce.

<?php
$url = add_query_arg(
    array(
        'action'     => 'delete_comment',
        'comment_id' => $comment_id,
    ),
    admin_url( 'admin-post.php' )
);
$protected_url = wp_nonce_url( $url, 'delete-comment_' . $comment_id );
?>
<a href='<?php echo esc_url( $protected_url ); ?>'>Delete comment</a>

Nonce-protecting a URL does not make a destructive action safe to perform with a simple GET request. For operations that change data, prefer a POST request and verify the nonce in the handler. A nonce on a link is appropriate when an administrative flow intentionally uses a protected URL and the server-side handler still checks permissions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Verifying admin forms and URLs

Use check_admin_referer() in the matching handler

For an admin form or admin URL, call check_admin_referer() with the same action string used to create the nonce.

<?php
check_admin_referer( 'delete-comment_' . $comment_id );

if ( ! current_user_can( 'moderate_comments' ) ) {
    wp_die( 'You are not allowed to delete comments.' );
}

$comment_id = absint( $_POST['comment_id'] ?? 0 );
// Validate that the ID is present and that the requested comment is the intended target.
// Perform the deletion only after validation and the capability check.
?>

With normal settings, failed verification stops the request and displays an error rather than allowing the operation to continue. Verify before changing data, sending email, charging a customer, or performing any other side effect.

Do not confuse a referer check with authorization

check_admin_referer() verifies the nonce and, in the relevant WordPress flow, the request context. It does not prove that the current account may edit the selected post, delete the selected comment, or administer the plugin. Check the capability that maps to the resource and operation immediately before performing the action.

Verifying AJAX requests

Generate and expose the token

Create a nonce with wp_create_nonce() and make it available to the JavaScript that sends the request. A common approach is localizing script data or using an inline configuration object.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<?php
$settings = array(
    'ajaxUrl' => admin_url( 'admin-ajax.php' ),
    'nonce'   => wp_create_nonce( 'delete-comment_' . $comment_id ),
);
wp_localize_script( 'my-plugin-script', 'MyPlugin', $settings );
?>

The browser then includes the nonce in the request, commonly in a field named _ajax_nonce or another name that the handler specifies.

fetch(MyPlugin.ajaxUrl, {
    method: 'POST',
    headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
    body: new URLSearchParams({
        action: 'delete_comment',
        comment_id: String(commentId),
        _ajax_nonce: MyPlugin.nonce
    })
});

Verify with check_ajax_referer()

In the AJAX callback, use the same action string and identify the request field if you chose a custom name.

<?php
function my_plugin_delete_comment_ajax() {
    check_ajax_referer( 'delete-comment_' . absint( $_POST['comment_id'] ?? 0 ), '_ajax_nonce' );

    if ( ! current_user_can( 'moderate_comments' ) ) {
        wp_send_json_error( array( 'message' => 'Permission denied.' ), 403 );
    }

    $comment_id = absint( $_POST['comment_id'] ?? 0 );
    if ( ! $comment_id ) {
        wp_send_json_error( array( 'message' => 'Invalid comment ID.' ), 400 );
    }

    // Confirm the comment exists and then perform the validated operation.
    wp_send_json_success();
}
add_action( 'wp_ajax_delete_comment', 'my_plugin_delete_comment_ajax' );
?>

check_ajax_referer() returns 1 when the nonce was generated 0–12 hours ago and 2 when it was generated 12–24 hours ago. By default, it terminates the request when verification fails. If your endpoint needs a JSON error envelope or a different recovery path, pass the function’s stop behavior accordingly and handle the failure response yourself; never continue to the protected operation.

Sending a nonce to the WordPress REST API

Cookie-authenticated REST requests from a logged-in session

For REST API requests made inside a WordPress login session, create a nonce with the special action wp_rest. Send it on every manual request in the X-WP-Nonce header. WordPress also accepts the _wpnonce parameter, but the header keeps the token out of the URL.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<?php
$rest_nonce = wp_create_nonce( 'wp_rest' );
?>
<script>
const restNonce = '<?php echo esc_js( $rest_nonce ); ?>';
fetch('/wp-json/wp/v2/posts/123', {
    method: 'POST',
    headers: {
        'X-WP-Nonce': restNonce,
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({title: 'Updated title'})
});
</script>

WordPress’s REST cookie authentication checks the login cookies and the nonce. If the required REST nonce is missing, the request is treated as unauthenticated rather than as an authenticated cookie request. A valid REST nonce still does not grant permission to edit post 123; the endpoint’s capability checks decide that.

Application passwords are separate

Cookie-based REST authentication is intended for requests made within the WordPress session. Application passwords, available since WordPress 5.6, are a separate authentication option for clients that are not operating inside that browser session. Do not send a cookie-session nonce as a substitute for credentials required by an external integration.

Nonce lifetime and session behavior

The default window is variable

WordPress’s default nonce setting is one day, implemented as two half-life ticks. In practice, a nonce is valid for a variable period between 12 and 24 hours, depending on when during the tick cycle it was created. The age values returned by check_ajax_referer() reflect the same two ranges: 1 for 0–12 hours and 2 for 12–24 hours.

Treat the token as time-limited, not as a one-request credential. If your application requires a shorter or independently managed lifetime, design that policy explicitly rather than assuming the default behaves like a strict 24-hour timer.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Login and logout can invalidate rendered tokens

Nonces are tied to the current user session. If a user logs in or out asynchronously, a nonce already rendered into an open page may no longer verify. Refresh the page or obtain a newly generated token after a session transition instead of retrying indefinitely with the stale value.

Logged-out visitors need an additional mechanism

For visitors who are not logged in, WordPress normally uses user ID 0 when generating nonces. That means all anonymous visitors can share the same user context for nonce purposes. If a guest action is important enough to protect individually, add a session mechanism through the nonce_user_logged_out filter and bind the action to that guest session. A public nonce alone is not an adequate identity or abuse-prevention system.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Nonce security boundaries

A nonce is one layer in a request’s defense. For every state-changing handler, apply the following controls in order:

  1. Verify the nonce using the function for the request context.
  2. Authenticate the user or session through WordPress’s normal mechanism.
  3. Check the precise capability for the operation and target resource with current_user_can() or an equivalent authorization check.
  4. Validate types, ranges, object ownership, and relationships in submitted data.
  5. Sanitize data for its destination and escape it when rendering output.
  6. Perform the side effect only after all checks pass, then return a response appropriate to the caller.

For example, a valid delete-comment_123 nonce does not authorize a subscriber to delete comment 123, does not prove that the submitted comment ID is the one displayed on the page, and does not make an unvalidated text field safe to store.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Which verification function should you use?

Request context Create the token Verify it Failure behavior and notes
Admin form wp_nonce_field( $action ) check_admin_referer( $action ) Normally terminates on failure; keep a separate capability check.
Admin or protected URL wp_nonce_url( $url, $action ) check_admin_referer( $action ) Prefer POST for data-changing operations; escape the final URL.
AJAX wp_create_nonce( $action ) check_ajax_referer( $action ) Returns age code 1 or 2 when valid and stops by default when invalid; customize only when you return your own error response.
Custom handler wp_create_nonce( $action ) wp_verify_nonce( $value, $action ) Returns a validity/age result for your code to interpret; you must decide how to report failure.
REST API with login cookies wp_create_nonce( 'wp_rest' ) REST cookie authentication checks the nonce Send X-WP-Nonce or _wpnonce on each request; missing tokens are treated as unauthenticated.

Using wp_verify_nonce() for custom handling

Use wp_verify_nonce() when the standard admin or AJAX functions do not fit your response format or transport. Read the submitted value, pass it with the exact action, and stop on a false result.

<?php
$value = sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ?? '' ) );
$result = wp_verify_nonce( $value, 'export-report' );

if ( false === $result ) {
    wp_send_json_error( array( 'message' => 'The security token is invalid or expired.' ), 403 );
}

if ( ! current_user_can( 'manage_options' ) ) {
    wp_send_json_error( array( 'message' => 'Permission denied.' ), 403 );
}

// Validate export parameters before generating the report.
?>

Do not use a custom verifier merely to avoid handling errors. The important requirement is that an invalid token cannot reach the protected operation.

Troubleshooting common failures

“Are you sure you want to do this?” or an invalid nonce error

  • Confirm that the action string is byte-for-byte identical during creation and verification.
  • Check that the submitted field is present and has not been renamed by JavaScript or a proxy.
  • Refresh the page if the user recently logged in, logged out, or switched accounts.
  • Verify that caching is not serving a page containing another user’s or an expired token. Do not cache personalized nonce-bearing HTML publicly.

AJAX returns an unexpected HTML error page

The default failure behavior of check_ajax_referer() terminates the request. If the browser expects JSON, configure the handler to detect failure and return a JSON error, while preserving the rule that no protected code runs after failure.

REST request becomes unauthenticated

  • Generate the token with the action exactly wp_rest.
  • Send it as X-WP-Nonce on every manual cookie-authenticated request, not only the first one.
  • Make sure the browser is sending the WordPress login cookies and that the page has not retained a token from an earlier session.
  • For a non-browser integration, use the authentication method intended for that client rather than relying on a browser-session nonce.

The nonce verifies but the operation is still rejected

That is expected when the current account lacks the required capability, the object does not exist, or submitted data fails validation. Keep those checks; a nonce is not an override for authorization or business rules.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Deployment checklist

Before shipping a plugin or REST change that adds or changes nonce handling:

  • Use a staging environment to exercise valid, expired, missing, altered, and cross-action tokens.
  • Test both the permitted and forbidden capability paths with different user roles.
  • Test after login, logout, and session switching so stale-page behavior is understood.
  • Check anonymous flows separately; decide whether user ID 0 is sufficient or whether a guest session is required.
  • Confirm that cache layers do not share personalized nonce-bearing pages.
  • Back up the site before significant plugin or application changes and keep a rollback path.
  • Log failures without recording complete nonce values, since a token should not become a new credential in your logs.

End-to-end pattern

A robust implementation follows one chain: choose a narrowly scoped action, create the token in the page or script, transmit it with the request, verify it in the matching context, check the user’s capability, validate every input, and only then perform the state change. The same pattern applies whether the transport is an admin form, a protected URL, an AJAX request, or a cookie-authenticated REST call; only the creation and verification APIs differ.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.