wp_create_nonce( string|int $action = -1 ): string
- Since
- 2.0.3, 4.0.0
- Source
wp-includes/pluggable.php:2537
Generates a short-lived, one-time-use style token scoped to the current user, their session, and a given action string, for use in forms, URLs, and AJAX requests. The token also depends on wp_get_session_token() and a rotating time window from wp_nonce_tick(), so the same action string produces a different value once the user logs out, switches sessions, or enough time passes. Pair it with wp_verify_nonce() or check_ajax_referer() on the receiving end, since creating a nonce alone does nothing to protect a request.
Compatibility
- WordPress
- since 4.0.0
- PHP
- 7.4–8.6-dev
- 6.7.7
- 6.8.8
- 6.9.7
- 7.0.4
- 7.1.0
Present in every tracked release (6.7.7 to 7.1.0), and compiles on PHP 7.4 through 8.6-dev.
Parameters
$actionstring|intoptional- Scalar value to add context to the nonce.Default:
-1
Return value
string- The token.
Code examples
Every example is editable and runs in a real WordPress booted in your browser by WordPress Playground. Press Run, then edit the code: clicking away re-runs it. Nothing is sent anywhere until you do.
Create a nonce for a delete-post link
Build the nonce that would be appended to a custom admin action URL for deleting post ID 2.
$post_id = 2;
$action = 'delete_post_' . $post_id;
$nonce = wp_create_nonce( $action );
$url = add_query_arg(
array(
'action' => 'my_plugin_delete_post',
'post' => $post_id,
'_wpnonce' => $nonce,
),
admin_url( 'admin-post.php' )
);
echo esc_html( 'Nonce: ' . $nonce ) . "\n";
echo esc_html( 'URL: ' . $url );The action string must be reproduced exactly when the request is verified, so build it from the same post ID rather than a hardcoded string.
Create and immediately verify a nonce to check the round trip
Confirm that a nonce created for one action string fails verification against a different action string on post 3.
$correct_action = 'update_price_3';
$wrong_action = 'update_price_4';
$nonce = wp_create_nonce( $correct_action );
$result_correct = wp_verify_nonce( $nonce, $correct_action );
$result_wrong = wp_verify_nonce( $nonce, $wrong_action );
echo esc_html( 'Verifies against matching action: ' . var_export( (bool) $result_correct, true ) ) . "\n";
echo esc_html( 'Verifies against mismatched action: ' . var_export( (bool) $result_wrong, true ) );wp_verify_nonce() returns 1 or 2 (truthy) on success and false on failure, not a plain boolean.
Common problems and fixes · 4
- Why does the nonce I generated fail verification a few minutes later?
- Why do logged-out users all get the same nonce for the same action?
- Why does a nonce that worked in one browser tab fail in another?
- Why did changing my action string break all my existing nonces?
Why does the nonce I generated fail verification a few minutes later?
Why do logged-out users all get the same nonce for the same action?
Why does a nonce that worked in one browser tab fail in another?
Why did changing my action string break all my existing nonces?
Alternatives and related functions
wp_verify_nonce- When you need to check a nonce that was previously created with wp_create_nonce() rather than generate a new one.
wp_nonce_field- When you need to output a hidden form field containing the nonce plus a referer field, instead of handling the raw string yourself.
wp_nonce_url- When you need to append a nonce to a URL's query string rather than embed it in a form.
check_ajax_referer- When you're handling an AJAX request and want nonce creation and verification plus a die() on failure handled in one call.
Performance profile
How much work a call to wp_create_nonce() does, and what it touches: the algorithmic scaling, the Zend instruction count per call across PHP versions, the hooks it hands control to, and the core code that calls it. Measured from the compiled opcodes, not a stopwatch, so every number is identical on any machine running the same PHP version, and every function in core is ranked by cost.
- Cost class
- Trivial
- Scaling
- Constant
- Instructions
- 27–33
- Plugin surface
- 1 hook
- Called by
- 50
Touches nothing outside its own arguments.
No loop in the body: the same number of instructions runs whatever you pass in.
Executed per call on PHP 8.5, depending on the branch taken. The body compiles to 33.
Third-party callbacks on 'nonce_user_logged_out' run inside this call, and their cost is not bounded by anything here.
50 places in core call this, so the cost is paid more often than your own code shows.
What it touches
- hookthird-party callbacks
apply_filters()called directly
Further down the call graph this can also reach option, cache, serialize, transient and query. Those are the worst case, several calls deep and usually down an error path, not what a normal call pays.
What one call costs · 2 distinct outcomes
One number would be a lie: the work depends on which branch runs. These are every distinct cost wp_create_nonce() can have, taken from its control-flow graph on PHP 8.5.
| When | Instructions | Calls it makes |
|---|---|---|
| always | 27 | wp_get_current_user(), wp_get_session_token(), wp_nonce_tick(), wp_hash() |
| always | 33 | wp_get_current_user(), apply_filters(), wp_get_session_token(), wp_nonce_tick(), wp_hash() |
Across PHP versions
| PHP | Compiled | Executed | Branches | Notes |
|---|---|---|---|---|
| 8.6-dev | 33 | 27–33 | 1 | |
| 8.5 | 33 | 27–33 | 1 | |
| 8.4 | 33 | 27–33 | 1 | 3 fewer instructions than PHP 8.3 |
| 8.3 | 36 | 30–36 | 1 | |
| 8.2 | 36 | 30–36 | 1 | |
| 8.1 | 36 | 30–36 | 1 | |
| 7.4 | 36 | 30–36 | 1 |
An instruction is not a fixed amount of time, so a matching count is not necessarily the same speed; what it rules out is a difference in the work itself.
Hooks and filters fired · 1
One hook fires while wp_create_nonce() runs, in this order:
- apply_filters( nonce_user_logged_out )filterline 2542 (+5 into the body)
Filters whether the user who generated the nonce is logged out.
Uses · 5
- wp_get_current_user()Retrieves the current user object.
- apply_filters()Calls the callback functions that have been added to a filter hook.
- wp_get_session_token()Retrieves the current session token from the logged_in cookie.
- wp_nonce_tick()Returns the time-dependent variable for nonce creation.
- wp_hash()Gets the hash of the given string.
Used by · 50
- Custom_Image_Header::step_1()Displays first step of custom header image page.
- WP_Comments_List_Table::handle_row_actions()Generates and displays row actions links.
- WP_Customize_Background_Image_Control::enqueue()Enqueue control related scripts/styles.
- WP_Customize_Header_Image_Control::enqueue()Enqueues control related scripts/styles.
- WP_Customize_Manager::get_nonces()Gets nonces for the Customizer.
- WP_Customize_Manager::handle_load_themes_request()Loads themes into the theme browsing/installation UI.
- WP_Customize_Nav_Menus::filter_nonces()Adds a nonce for customizing menus.
- WP_Customize_Widgets::refresh_nonces()Refreshes the nonce for widget updates.
- WP_Media_List_Table::column_parent()Handles the parent column output.
- WP_Plugin_Dependencies::check_plugin_dependencies_during_ajax()Checks plugin dependencies after a plugin is installed via AJAX.
- WP_Privacy_Data_Export_Requests_List_Table::column_email()Actions column.
- WP_Privacy_Data_Export_Requests_List_Table::column_next_steps()Displays the next steps column.
Show all 50
- WP_Privacy_Data_Removal_Requests_List_Table::column_email()Outputs the Actions column.
- WP_Privacy_Data_Removal_Requests_List_Table::column_next_steps()Outputs the Next steps column.
- WP_REST_Autosaves_Controller::prepare_item_for_response()Prepares the revision for the REST response.
- WP_Site_Health::enqueue_scripts()Enqueues the site health scripts.
- WP_Site_Health::get_test_rest_availability()Tests if the REST API is accessible.
- WP_Site_Health::wp_cron_scheduled_check()Runs the scheduled event to check and update the latest site health status for the website.
- _admin_notice_post_locked()Outputs the HTML for the notice to say that someone else is editing or has taken over editing of this post.
- _list_meta_row()Outputs a single row of public meta data in the Custom Fields meta box.
- _wp_dashboard_recent_comments_row()Outputs a row for the Recent Comments widget.
- activate_plugin()Attempts activation of plugin in a "sandbox" and redirects on success.
- compression_test()Tests support for compressing JavaScript from PHP.
- edit_form_image_editor()Displays the image and editor in the post editor
- get_media_item()Retrieves HTML form for modifying the image attachment.
- install_plugins_favorites_form()Shows a username form for the favorites page.
- media_upload_form()Outputs the legacy media upload form.
- post_preview()Saves a draft or manually autosaves for the purpose of showing a post preview.
- rest_cookie_check_errors()Checks for errors when using cookie-based authentication.
- resume_plugin()Tries to resume a single plugin.
- resume_theme()Tries to resume a single theme.
- wp_ajax_install_plugin()Handles installing a plugin via AJAX.
- wp_ajax_install_theme()Handles installing a theme via AJAX.
- wp_ajax_query_themes()Handles getting themes from themes_api() via AJAX.
- wp_ajax_replyto_comment()Handles replying to a comment via AJAX.
- wp_ajax_rest_nonce()Handles renewing the REST API nonce via AJAX.
- wp_block_theme_activate_nonce()Set a JavaScript constant for theme activation.
- wp_default_packages_inline_scripts()Adds inline scripts required for the WordPress JavaScript packages.
- wp_default_scripts()Registers all WordPress scripts.
- wp_enqueue_media()Enqueues all scripts, styles, settings, and templates necessary to use all media JS APIs.
- wp_get_plugin_action_button()Gets the markup for the plugin install action button.
- wp_heartbeat_settings()Default settings for heartbeat.
- wp_image_editor()Loads the WP image-editing interface.
- wp_localize_community_events()Localizes community events data that needs to be passed to dashboard.js.
- wp_nonce_field()Retrieves or display nonce hidden field for forms.
- wp_nonce_url()Retrieves URL with nonce added to URL query.
- wp_plupload_default_settings()Prints default Plupload arguments.
- wp_prepare_attachment_for_js()Prepares an attachment post object for JS, where it is expected to be JSON-encoded and fit into an Attachment model.
- wp_prepare_revisions_for_js()Prepare revisions for JavaScript.
- wp_refresh_heartbeat_nonces()Adds the latest Heartbeat and REST API nonce to the Heartbeat response.
Source code
function wp_create_nonce( $action = -1 ) { $user = wp_get_current_user(); $uid = (int) $user->ID; if ( ! $uid ) { /** This filter is documented in wp-includes/pluggable.php */ $uid = apply_filters( 'nonce_user_logged_out', $uid, $action ); } $token = wp_get_session_token(); $i = wp_nonce_tick( $action ); return substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 ); }Changelog
Introduced in 2.0.3. Unchanged from 6.7.7 through 7.1.0.
Signature, return type and hooks compared across 5 parsed releases.
About this page
- Parsed data
- Generated from the wordpress-develop 7.1.0 tag, from
src/wp-includes/pluggable.php, and regenerated for each WordPress release so it tracks the code rather than a snapshot of it. - Corrections
- Something wrong on this page? Report it and it gets fixed in the next regeneration.