Cookie nonce is invalid – Multisite

I get following messages:

Applicaiton password plugin

Cookie nonce is invalid

iThemes Security

A nonce security check failed, preventing the request from completing as expected. Please try reloading the page and trying again.

…when I try to save settings in network (subdirectory multisite) admin. But I don’t get this messages if I use the settings panel for a plugin within a site.

I did some debugging and what I found was that wp_verify_nonce() always returns false. The cookie token never match the expected token. I have no idea why WordPress is behaving in this way.

Do someone have an idea why WordPress nonce is behaving in this way? How can I fix it?

I’m using Bedrock and here is my settings:

define('WP_HOME', 'http://my-local-cms.dev');
define('WP_SITEURL', 'http://my-local-cms.dev/backend');
define('CONTENT_DIR', '/app');

define('ADMIN_COOKIE_PATH', "https://wordpress.stackexchange.com/");
define('COOKIE_DOMAIN', '');
define('COOKIEPATH', '');
define('SITECOOKIEPATH', '');

define('WP_ALLOW_MULTISITE', true);
define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', false);
define('DOMAIN_CURRENT_SITE', 'my-local-cms.dev');
define('PATH_CURRENT_SITE', "https://wordpress.stackexchange.com/");
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);

1 Answer
1

I found the problem.

The links to the Network Admin are incorrect. For example, network users have:

http://my-local-cms.dev/wp-admin/network/

It should be (if wordpress core is located in backend/)

http://my-local-cms.dev/backend/wp-admin/network/

If you visit the first link and add /backend/ before wp-admin in the browser, then the network admin will behave correctly.

Fix

Edit 2017-08-30
New solution:

public function fix_network_admin_url($path, $scheme) {
    $path = ltrim($path, "https://wordpress.stackexchange.com/");
    return str_replace('/wp-admin/network', '/backend/wp-admin/network', $path);
}
add_filter('network_admin_url','fix_network_admin_url', 10, 3);

end of 2017-08-30 edit

The way I chose to solve this is to make a separate network admin menu with corrected links. This is not an elegant solution, but I don’t know how to fix the URLs only for the native Network Admin menu and leave the rest of the links intact (see “Other potential solutions”).

My solution is similar to this (add to either to function.php in theme or create a plugin):

add_action('admin_head', 'admin_head_network_menu');
add_action('admin_bar_menu', 'custom_network_admin_bar_menu', 20);

function admin_head_network_menu()
{
    echo '<style type="text/css">#wp-admin-bar-my-sites-super-admin {display: none}</style>';
}

function custom_network_admin_bar_menu($adminBar)
{
    // Don't add network admin bar for non super admins
    if (!current_user_can('manage_network')) {
        return;
    }

    $mainMenuID = 'my-new-network-admin-menu';

    $adminBar->add_menu([
        'id' => $mainMenuID,
        'title' => __('Network Admin'),
        'href' => new_admin_url(),
    ]);

    $adminBar->add_menu([
        'id' => $mainMenuID.'-sites',
        'parent' => $mainMenuID,
        'title' => __('Network Sites'),
        'href' => new_admin_url('sites.php'),
    ]);

    $adminBar->add_menu([
        'id' => $mainMenuID.'-users',
        'parent' => $mainMenuID,
        'title' => __('Network Users'),
        'href' => new_admin_url('users.php'),
    ]);

    $adminBar->add_menu([
        'id' => $mainMenuID.'-plugins',
        'parent' => $mainMenuID,
        'title' => __('Network Plugins'),
        'href' => new_admin_url('plugins.php'),
    ]);

    $adminBar->add_menu([
        'id' => $mainMenuID.'-settings',
        'parent' => $mainMenuID,
        'title' => __('Network Settings'),
        'href' => new_admin_url('settings.php'),
    ]);
}

function new_admin_url($path="")
{
    $url = network_admin_url($path);
    return str_replace('/wp-admin/network', '/backend/wp-admin/network', $url);
}

Other potential solutions

If you have a (sub)domain multisite installation, checkout “felixarntz/multisite-fixes” on Github (mu-plugins/wpms-site-url-fixer.php).

I think maybe this can be fixed with a change in .htaccess. For number of reasons this was not an option for my project. But if someone else want to have a go, here is an example .htaccess for Bedrock:

RewriteEngine On
RewriteBase /wp/
RewriteRule ^index\.php$ - [L]

# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]

Leave a Comment