blog-img
blog-img
blog-img

You could think “I just need to install a plugin, there are at least a dozen of plugins that do this”. That’s true, there are a lot of plugins that limit the access to the dashboard of WordPress, but are you sure that a plugin is always the best choose?
If you want limit the access to your WordPress dashboard avoiding side effects, or if you tried to do it programmatically by yourself and something gone wrong, this is the article which you are looking for.

Why avoid to use a plugin

There are a lot of plugins that can help you to achieve this result, just few example:

So why should you hide your WordPress dashboard programmatically, instead of use one of these plugins? Because an elevated number of plugins can cause many side effects. Foremost it can increase the loading time of your site, making it slower and unpleasant for your users. In addition you have to update periodically one more plugin and, if the plugin is not longer updated and supported by its author, it could become a security risk for all your site.
In my opinion, there is really no reason to take these risks, because you can achieve the same result just writing down very few lines of code.

Hide the WordPress dashboard avoiding the AJAX trap

As I told, it’s possible to limit access to the dashboard with few lines of code, it’s actually just a redirect with an if statement, so why many customers have failed and asked us support for this easy task? Because they have not considered the AJAX trap.
So let me show you the wrong way to achieve it. Usually the code of our customers was something like that:

add_action( 'admin_init', 'my_custom_dashboard_access_handler');
function my_custom_dashboard_access_handler() {
   // Check if the current user has admin capabilities
   if ( !current_user_can( 'manage_users' )) {
      wp_redirect( home_url() );
      exit;
   }
}

What is wrong in this code? Actually there is nothing really wrong, but there is something missing. Using this code, you forget that every ajax call handled by WordPress is sent to www.yoursite.com/wp-admin/wp-ajax.php which is an admin page. This mean that the code below blocks every ajax call of your site.
In the light of this new consideration, this is the working code:

// Coould be better adds the function to the 'init' hook and check later if it's an admin page
add_action( 'init', 'my_custom_dashboard_access_handler');
function my_custom_dashboard_access_handler() {
   // Check if the current page is an admin page
   // && check if the current user has admin capabilities
   // && and ensure that this is not an ajax call
   if ( is_admin() && !current_user_can( 'manage_users' ) && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX )) {
      wp_redirect( home_url() );
      exit;
   }
}

NOTE: You may read around that current_user_can( 'manage_users' ) and current_user_can( 'administrator' ) return always the same result. This is wrong because current_user_can( 'administrator' ) creates troubles in multisite installations, because it return false for superadmins.

Limit access to the admin panel only to certain roles

If you want to limit the access to many specific roles and you want avoid to add such many OR statement, you can do in this way:

// Could be better adds the function to the 'init' hook and check later if it's an admin page
add_action( 'init', 'my_custom_dashboard_access_handler');
function my_custom_dashboard_access_handler() {
   // Check if the current page is an admin page
   // && and ensure that this is not an ajax call
   if ( is_admin() && !( defined( 'DOING_AJAX' ) && DOING_AJAX ) ){
      //Get all capabilities of the current user
      $user = get_userdata( get_current_user_id() );
      $caps = ( is_object( $user) ) ? array_keys($user->allcaps) : array();
      //All capabilities/roles listed here are not able to see the dashboard
      $block_access_to = array('subscriber', 'contributor', 'my-custom-role', 'my-custom-capability');
      if(array_intersect($block_access_to, $caps)) {
         wp_redirect( home_url() );
         exit;
      }
   }
}

Conclusion

You have discovered that rely you to third-part plugins is not always a good idea, it can have some side effects and sometime,like in this case, the result is really really easy to achieve the same result programmatically.
If you have any question or you think that that something in the code should be even improved, or if you liked the article and you want just say thank you, it would be really appreciated to see a comment right below.

blog-img
blog-img

Comments 6

  • HI Antonio,
    Thanks for the awesome sharing for the code.
    “Limit access to the admin panel only to certain roles ”
    I try the code as above on my website and it works perfectly !
    However I found a loophole which i need your advise.
    The restriction works on Desktop.
    I tried to login via my mobile( as a vendor role ), then go to xxx.com/admin ; i can view the Dashboard with all ADMIN functions ! ( Does Not Work on Mobile )
    I am using woocommerce, and there’s couple of roles.
    I would like to restrict dashboard for all roles except admin and editor
    Looking forward for your advise.
    Thanks for the awesome work !

    • No, you need to create a new plugin, see the repository, which is linked at the beginning of the article. You should not edit any WordPress core file.

  • thanks i studied some tutorial, and i learn a little bit about funtion.php and and added code their it works now.

  • Hello,
    Is it possible to limit backend access to one user on user ID or Username?
    The particular user needs to be an admin for some kind of functionality, but i don’t want him/her to have access to the backend.
    Greetings Bart

Comments are closed.