Title: wp_verify_nonce
Published: April 25, 2014
Last modified: August 20, 2026

---

# wp_verify_nonce( string $nonce, string|int $action = -1 ): int|false

## In this article

 * [Description](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#description)
 * [Parameters](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#parameters)
 * [Return](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#return)
 * [More Information](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#more-information)
 * [Source](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#source)
 * [Hooks](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#hooks)
 * [Related](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#related)
 * [Changelog](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#changelog)
 * [User Contributed Notes](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#user-contributed-notes)

[ Back to top](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#wp--skip-link--target)

Verifies that a correct security nonce was used with time limit.

## 󠀁[Description](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#description)󠁿

A nonce is valid for between 12 and 24 hours (by default).

## 󠀁[Parameters](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#parameters)󠁿

 `$nonce`stringrequired

Nonce value that was used for verification, usually via a form field.

`$action`string|intoptional

Should give context to what is taking place and be the same when nonce was created.

Default:`-1`

## 󠀁[Return](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#return)󠁿

 int|false 1 if the nonce is valid and generated between 0-12 hours ago, 2 if the
nonce is valid and generated between 12-24 hours ago.
 False if the nonce is invalid.

## 󠀁[More Information](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#more-information)󠁿

The function is used to verify the nonce sent in the current request usually accessed
by the [$_REQUEST](http://php.net/manual/en/reserved.variables.request.php) PHP 
variable.

Nonces should never be relied on for authentication or authorization, access control.
Protect your functions using [current_user_can()](https://developer.wordpress.org/reference/functions/current_user_can/),
always assume Nonces can be compromised.

## 󠀁[Source](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#source)󠁿

    ```php
    function wp_verify_nonce( $nonce, $action = -1 ) {
    	$nonce = (string) $nonce;
    	$user  = wp_get_current_user();
    	$uid   = (int) $user->ID;
    	if ( ! $uid ) {
    		/**
    		 * Filters whether the user who generated the nonce is logged out.
    		 *
    		 * @since 3.5.0
    		 *
    		 * @param int        $uid    ID of the nonce-owning user.
    		 * @param string|int $action The nonce action, or -1 if none was provided.
    		 */
    		$uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
    	}

    	if ( empty( $nonce ) ) {
    		return false;
    	}

    	$token = wp_get_session_token();
    	$i     = wp_nonce_tick( $action );

    	// Nonce generated 0-12 hours ago.
    	$expected = substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );
    	if ( hash_equals( $expected, $nonce ) ) {
    		return 1;
    	}

    	// Nonce generated 12-24 hours ago.
    	$expected = substr( wp_hash( ( $i - 1 ) . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );
    	if ( hash_equals( $expected, $nonce ) ) {
    		return 2;
    	}

    	/**
    	 * Fires when nonce verification fails.
    	 *
    	 * @since 4.4.0
    	 *
    	 * @param string     $nonce  The invalid nonce.
    	 * @param string|int $action The nonce action.
    	 * @param WP_User    $user   The current user object.
    	 * @param string     $token  The user's session token.
    	 */
    	do_action( 'wp_verify_nonce_failed', $nonce, $action, $user, $token );

    	// Invalid nonce.
    	return false;
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/pluggable.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/7.1/src/wp-includes/pluggable.php#L2474)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/7.1/src/wp-includes/pluggable.php#L2474-L2523)

## 󠀁[Hooks](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#hooks)󠁿

 [apply_filters( ‘nonce_user_logged_out’, int $uid, string|int $action )](https://developer.wordpress.org/reference/hooks/nonce_user_logged_out/)

Filters whether the user who generated the nonce is logged out.

 [do_action( ‘wp_verify_nonce_failed’, string $nonce, string|int $action, WP_User $user, string $token )](https://developer.wordpress.org/reference/hooks/wp_verify_nonce_failed/)

Fires when nonce verification fails.

## 󠀁[Related](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#related)󠁿

| Uses | Description | 
| [wp_get_session_token()](https://developer.wordpress.org/reference/functions/wp_get_session_token/)`wp-includes/user.php` |

Retrieves the current session token from the logged_in cookie.

  | 
| [wp_nonce_tick()](https://developer.wordpress.org/reference/functions/wp_nonce_tick/)`wp-includes/pluggable.php` |

Returns the time-dependent variable for nonce creation.

  | 
| [wp_hash()](https://developer.wordpress.org/reference/functions/wp_hash/)`wp-includes/pluggable.php` |

Gets the hash of the given string.

  | 
| [wp_get_current_user()](https://developer.wordpress.org/reference/functions/wp_get_current_user/)`wp-includes/pluggable.php` |

Retrieves the current user object.

  | 
| [apply_filters()](https://developer.wordpress.org/reference/functions/apply_filters/)`wp-includes/plugin.php` |

Calls the callback functions that have been added to a filter hook.

  | 
| [do_action()](https://developer.wordpress.org/reference/functions/do_action/)`wp-includes/plugin.php` |

Calls the callback functions that have been added to an action hook.

  |

[Show 2 more](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#)
[Show less](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#)

| Used by | Description | 
| [WP_Recovery_Mode::handle_exit_recovery_mode()](https://developer.wordpress.org/reference/classes/wp_recovery_mode/handle_exit_recovery_mode/)`wp-includes/class-wp-recovery-mode.php` |

Handles a request to exit Recovery Mode.

  | 
| [wp_edit_theme_plugin_file()](https://developer.wordpress.org/reference/functions/wp_edit_theme_plugin_file/)`wp-admin/includes/file.php` |

Attempts to edit a file for a theme or plugin.

  | 
| [rest_cookie_check_errors()](https://developer.wordpress.org/reference/functions/rest_cookie_check_errors/)`wp-includes/rest-api.php` |

Checks for errors when using cookie-based authentication.

  | 
| [wp_handle_comment_submission()](https://developer.wordpress.org/reference/functions/wp_handle_comment_submission/)`wp-includes/comment.php` |

Handles the submission of a comment, usually posted to wp-comments-post.php via a comment form.

  | 
| [wp_ajax_destroy_sessions()](https://developer.wordpress.org/reference/functions/wp_ajax_destroy_sessions/)`wp-admin/includes/ajax-actions.php` |

Handles destroying multiple open sessions for a user via AJAX.

  | 
| [WP_Plugin_Install_List_Table::prepare_items()](https://developer.wordpress.org/reference/classes/wp_plugin_install_list_table/prepare_items/)`wp-admin/includes/class-wp-plugin-install-list-table.php` |  | 
| [wp_autosave()](https://developer.wordpress.org/reference/functions/wp_autosave/)`wp-admin/includes/post.php` |

Saves a post submitted with XHR.

  | 
| [wp_ajax_heartbeat()](https://developer.wordpress.org/reference/functions/wp_ajax_heartbeat/)`wp-admin/includes/ajax-actions.php` |

Handles the Heartbeat API via AJAX.

  | 
| [request_filesystem_credentials()](https://developer.wordpress.org/reference/functions/request_filesystem_credentials/)`wp-admin/includes/file.php` |

Displays a form to the user to request for their FTP/SSH details in order to connect to the filesystem.

  | 
| [Custom_Image_Header::step()](https://developer.wordpress.org/reference/classes/custom_image_header/step/)`wp-admin/includes/class-custom-image-header.php` |

Gets the current step.

  | 
| [check_admin_referer()](https://developer.wordpress.org/reference/functions/check_admin_referer/)`wp-includes/pluggable.php` |

Ensures intent by verifying that a user was referred from another admin page with the correct security nonce.

  | 
| [check_ajax_referer()](https://developer.wordpress.org/reference/functions/check_ajax_referer/)`wp-includes/pluggable.php` |

Verifies the Ajax request to prevent processing requests external of the blog.

  | 
| [redirect_canonical()](https://developer.wordpress.org/reference/functions/redirect_canonical/)`wp-includes/canonical.php` |

Redirects incoming links to the proper URL based on the site url.

  | 
| [_show_post_preview()](https://developer.wordpress.org/reference/functions/_show_post_preview/)`wp-includes/revision.php` |

Filters the latest content for preview from the post autosave.

  | 
| [signup_nonce_check()](https://developer.wordpress.org/reference/functions/signup_nonce_check/)`wp-includes/ms-functions.php` |

Processes the signup nonce created in [signup_nonce_fields()](https://developer.wordpress.org/reference/functions/signup_nonce_fields/) .

  |

[Show 10 more](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#)
[Show less](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#)

## 󠀁[Changelog](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#changelog)󠁿

| Version | Description | 
| [2.0.3](https://developer.wordpress.org/reference/since/2.0.3/) | Introduced. |

## 󠀁[User Contributed Notes](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#user-contributed-notes)󠁿

 1.   [Skip to note 4 content](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#comment-content-660)
 2.    [Codex](https://profiles.wordpress.org/codex/)  [  11 years ago  ](https://developer.wordpress.org/reference/functions/wp_verify_nonce/#comment-660)
 3.  [You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_verify_nonce%2F%23comment-660)
     Vote results for this note: 4[You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_verify_nonce%2F%23comment-660)
 4.  **Example**
      Verify an nonce created with `wp_create_nonce()`:
 5.      ```php
         <?php
         // Step A: Create an nonce, and add it as a query var in a link to perform an action.
         $nonce = wp_create_nonce( 'my-nonce' );
         echo "<a href='myplugin.php?_wpnonce={$nonce}'>" . __( 'Save Something', 'textdomain' ) . "</a>";
         ?>
         ```
     
 6.      ```php
         // Step B: In our file that handles the request, verify the nonce.
         $nonce = $_REQUEST['_wpnonce'];
         if ( ! wp_verify_nonce( $nonce, 'my-nonce' ) ) {
         	die( __( 'Security check', 'textdomain' ) ); 
         } else {
         	// Do stuff here.
         }
         ```
     
 7.  You may also decide to take different actions based on the age of the nonce:
 8.      ```php
         $nonce = wp_verify_nonce( $nonce, 'my-nonce' );
         switch ( $nonce ) {
         	case 1:
         		echo 'Nonce is less than 12 hours old';
         		break;
         	case 2:
         		echo 'Nonce is between 12 and 24 hours old';
         		break;
         	default:
         		exit( 'Nonce is invalid' );
         }
         ```
     
 9.   [Log in to add feedback](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_verify_nonce%2F%3Freplytocom%3D660%23feedback-editor-660)
 10.  [Skip to note 5 content](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#comment-content-4725)
 11.   [WordProof](https://profiles.wordpress.org/wordproof/)  [  6 years ago  ](https://developer.wordpress.org/reference/functions/wp_verify_nonce/#comment-4725)
 12. [You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_verify_nonce%2F%23comment-4725)
     Vote results for this note: 3[You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_verify_nonce%2F%23comment-4725)
 13. Per the WordPress Coding Standards, this is the way as to verify a nonce:
 14.     ```php
         if ( isset( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( $_REQUEST['_wpnonce'], 'wpdocs-my-nonce' ) ) {
     
           //do you action
     
         } else {
     
           die( __( 'Security check', 'textdomain' ) ); 
     
         }
         ```
     
 15.  * Source?
      * [Gerard Reches](https://profiles.wordpress.org/gerardreches/) [3 years ago](https://developer.wordpress.org/reference/functions/wp_verify_nonce/#comment-6886)
 16.  [Log in to add feedback](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_verify_nonce%2F%3Freplytocom%3D4725%23feedback-editor-4725)
 17.  [Skip to note 6 content](https://developer.wordpress.org/reference/functions/wp_verify_nonce/?output_format=md#comment-content-5066)
 18.   [Roy Orbitson](https://profiles.wordpress.org/lev0/)  [  5 years ago  ](https://developer.wordpress.org/reference/functions/wp_verify_nonce/#comment-5066)
 19. [You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_verify_nonce%2F%23comment-5066)
     Vote results for this note: -1[You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_verify_nonce%2F%23comment-5066)
 20. This system is not very accurate and the comment about the return values is incorrect.
     The value `1` means < 12 hours old, but `2` means anywhere from 1 second to < 
     24 hours old.
 21. Observe what happens to the nonce tick value over a day:
 22. local time ~~~ seconds since epoch ~~~ tick
      2021-05-20T00:00:00+03:00 ~~~ 1621458000
     ~~~ 37534 2021-05-20T01:00:00+03:00 ~~~ 1621461600 ~~~ 37534 2021-05-20T02:00:
     00+03:00 ~~~ 1621465200 ~~~ 37534 2021-05-20T03:00:00+03:00 ~~~ 1621468800 ~~~
     37534 2021-05-20T04:00:00+03:00 ~~~ 1621472400 ~~~ 37535 2021-05-20T05:00:00+03:
     00 ~~~ 1621476000 ~~~ 37535 2021-05-20T06:00:00+03:00 ~~~ 1621479600 ~~~ 37535
     2021-05-20T07:00:00+03:00 ~~~ 1621483200 ~~~ 37535 2021-05-20T08:00:00+03:00 ~
     ~~ 1621486800 ~~~ 37535 2021-05-20T09:00:00+03:00 ~~~ 1621490400 ~~~ 37535 2021-
     05-20T10:00:00+03:00 ~~~ 1621494000 ~~~ 37535 2021-05-20T11:00:00+03:00 ~~~ 1621497600
     ~~~ 37535 2021-05-20T12:00:00+03:00 ~~~ 1621501200 ~~~ 37535 2021-05-20T13:00:
     00+03:00 ~~~ 1621504800 ~~~ 37535 2021-05-20T14:00:00+03:00 ~~~ 1621508400 ~~~
     37535 2021-05-20T15:00:00+03:00 ~~~ 1621512000 ~~~ 37535 2021-05-20T16:00:00+03:
     00 ~~~ 1621515600 ~~~ 37536 2021-05-20T17:00:00+03:00 ~~~ 1621519200 ~~~ 37536
     2021-05-20T18:00:00+03:00 ~~~ 1621522800 ~~~ 37536 2021-05-20T19:00:00+03:00 ~
     ~~ 1621526400 ~~~ 37536 2021-05-20T20:00:00+03:00 ~~~ 1621530000 ~~~ 37536 2021-
     05-20T21:00:00+03:00 ~~~ 1621533600 ~~~ 37536 2021-05-20T22:00:00+03:00 ~~~ 1621537200
     ~~~ 37536 2021-05-20T23:00:00+03:00 ~~~ 1621540800 ~~~ 37536
 23. …and over the boundary of a tick:
 24. local time ~~~ seconds since epoch ~~~ tick
      2021-05-20T14:59:58+03:00 ~~~ 1621511998
     ~~~ 37535 2021-05-20T14:59:59+03:00 ~~~ 1621511999 ~~~ 37535 2021-05-20T15:00:
     00+03:00 ~~~ 1621512000 ~~~ 37535 2021-05-20T15:00:01+03:00 ~~~ 1621512001 ~~~
     37536 2021-05-20T15:00:02+03:00 ~~~ 1621512002 ~~~ 37536
 25. In this example, you can see that a nonce generated at 3pm and verified one second
     later will return `2` because of the tick change. The ticks do not align with 
     timezones due to their basis in universal time, so nonces will always appear “
     old” to your code at certain times of the day.
 26.  * You’re right, but it doesn’t matter if the function returns 1 or 2 because 
        this function is use in an if clause and therefore the value is converted to
        a boolean which will be true for any value that is not 0. The check will only
        fail if the hashes don’t match.
      * [mumbomedia](https://profiles.wordpress.org/mumbomedia/) [5 years ago](https://developer.wordpress.org/reference/functions/wp_verify_nonce/#comment-5725)
      * @mumbomedia not all code uses the return value as a boolean, and its usage 
        in an `if` does not change the fact that, by default, a nonce may become invalid
        in 12 hours, i.e. **half** the time specified in the description. For that 
        reason, I wrote [a plugin that makes nonces last the expected duration](https://wordpress.org/plugins/noncensible/).
      * [Roy Orbitson](https://profiles.wordpress.org/lev0/) [2 years ago](https://developer.wordpress.org/reference/functions/wp_verify_nonce/#comment-7275)
 27.  [Log in to add feedback](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_verify_nonce%2F%3Freplytocom%3D5066%23feedback-editor-5066)

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_verify_nonce%2F)
before being able to contribute a note or feedback.