Skip to content

Instantly share code, notes, and snippets.

@rmpel
Last active April 22, 2024 18:45
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rmpel/703ba65e2870423ac1be47d8ef0fc7d1 to your computer and use it in GitHub Desktop.
Save rmpel/703ba65e2870423ac1be47d8ef0fc7d1 to your computer and use it in GitHub Desktop.
WordPress REST-API in website, NONCE problems when authenticating or de-authenticating (login / logout)
<?php
// sent an updated nonce to the front-end on each request
add_filter( 'rest_post_dispatch', function( WP_REST_Response $response, WP_REST_Server $rest, WP_REST_Request $request) {
$response->header('X-WP-Nonce', wp_create_nonce( 'wp_rest' ));
return $response;
}, PHP_INT_MAX, 3);
// wp_create_nonce relies on user-id from global user object, and authentication cookie.
// both are INCORRECT after programmatic log-in or log-out.
// Really, WordPress? You should do this for us!
// make sure memory cache of the cookie matches the cookie just sent to the browser
// on log-in, set the global $_COOKIE to the correct value
// todo: see if more cookies need this.
add_action('set_logged_in_cookie', function($cookie_value){
$_COOKIE[ LOGGED_IN_COOKIE ] = $cookie_value;
}, PHP_INT_MAX);
// on log-out, clear the global $_COOKIE the same way wp_logout() does.
// todo: see if more cookies need this.
add_action('clear_auth_cookie', function(){
$_COOKIE[ LOGGED_IN_COOKIE ] = ' ';
});
// set the global user to the correct user after programmatically logging in or out
// on log-in, update the global $current_user to the newly logged-in user
add_action('wp_login', function($login, $user){
wp_set_current_user( $user->ID );
}, PHP_INT_MAX, 2);
// on log-out, invalidate the global user object.
add_action('wp_logout', function(){
wp_set_current_user( 0 );
}, PHP_INT_MAX);
// add the current nonce to javascript
add_action('wp_head', function(){
print '<script>window.nonce = '. json_encode(wp_create_nonce( 'wp_rest' )) .';</script>';
});
/* over simplified. the window.nonce variable is a little exposed ... */
// send Nonce on request
$(document).ajaxSend(function (event, xhr, settings) {
xhr.setRequestHeader('X-WP-Nonce', window.nonce);
});
// receive Nonce and store. Make sure the PHP above does it's job, or add checks to see if the nonce is actually there.
$(document).ajaxComplete(function (event, xhr, settings) {
window.nonce = xhr.getResponseHeader('X-WP-Nonce');
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment