WordPress is creating nonce as a logged in user but verifying it incorrectly
I’m having trouble validating a nonce created with
wp_create_nonce() inside a hidden input with the name nonce in an html form:
<input type="hidden" name="nonce" value="<?php echo wp_create_nonce('action_name'); ?>" />
The form submission is done via ajax and validated with
check_ajax_referer('action_name','nonce'). This always returns
-1. All REST endpoints have been tested without nonces and work 100% fine.
The issue seems to stem from wp’s user identifcation.
My debugging so far
wp_create_nonce('action_name') creates a nonce hashing various variables including the user id and the action.
I submit an ajax call which calls
check_ajax_referer('action_name','nonce'). This in turn calls
wp_verify_nonce($nonce,$action) which verifies the nonce by hashing the same variables and comparing the two.
Reverse engineering to locate problem
My problem is that
wp_create_nonce('action_name') is being created with the correct user id. However, when I run
check_ajax_referer('action_name','nonce') which calls
wp_verify_nonce($nonce,$action) which in turn calls
wp_get_current_user(); no user is found (user id is 0).
Evidence the problem is to do with user id
If I temporarily edit wp-includes/pluggable.php to force my user id, the nonce validation works fine. It’s as if ajax requests to a known and valid endpoint are being treated as if the user is logged out regardless of whether they are or not.
I’m clearly missing something here, but I have no idea what.