Puddinq.com sharing knowledge

WordPress nonce why?, how and show me

WordPress nonce why?, how and show me

WordPress nonce has been available for a while, but if you are just starting to use it here is why, how and a copy and past example.

Why use nonce with WordPress?

Lets say you have two pages in your admin, page one and page two. Page one is a settings screen but page two takes care of some functions you do not want accessible without knowing the admin has the right intentions.

function example_pages()
{
    add_options_page(
        __('Page one settings', 'your-language'),
        __('Page one', 'your-language'),
        'manage_options',
        'page-one',
        'page_one_page');

    add_submenu_page(
        null,
        __('Page two', 'guest-writer'),
        __('Page two', 'guest-writer'),
        'manage_options',
        'page-two',
        'page_two_page'
    );

}

add_action('admin_menu', 'example_pages');

In the above, the first is an option page and the second a submenu page. The parent is set to null so it is never revealed in the admin menu.

How do we make it save

We need two functions for the pages, and we want the first to have a link to the (second) hidden page, but how do you do that savely.

  • Show the link only when requirements have been met.
  • Give the link an unique handle.

Example:

function page_one_page()
{
    echo '<div class="wrap">';

    echo '<h1>';
    echo esc_html(get_admin_page_title());
    echo '</h1>';

    $path = 'admin.php?page=page-two';
    $url = wp_nonce_url( $path, 'management', 'nonsense' );

    if (is_admin()) {
        echo "<a href='{$url}'>";
        echo __('Do hidden function', 'your-language');
        echo '</a>';
        echo '</div>';
    }
}

By using the wp_nonce_url() function we add &nonsense=vd6f4f to the url, the only thing you have to do on the second page is test if the value is still valid (something like 24 hours after created)

function page_two_page()
{
    echo '<div class="wrap">';

    echo '<h1>';
    echo esc_html(get_admin_page_title());
    echo '</h1>';

    check_admin_referer('management', 'nonsense');
    
    echo 'you did it';

    echo '</div>';
}

Now if you follow the link on the on the first page you get to the second page. If you use the direct link (without a nonce generated by the first page) you will not be allowed to see the page.

working link:

/wp-admin/admin.php?page=page-two&nonsense=69d6df5313

non-working link:

/wp-admin/admin.php?page=page-two

To see it all working copy the 3 pieces of code to your functions.php in your theme folder.