Don’t allow access to wp-admin but allow admin-ajax requests to be fulfilled on frontend?

I have a site that requires users to have an acccount to use it. I don’t want certain user roles to have access to wp-admin. All account changes should happen on the frontend account management templates. If a user tries to access wp-admin I want to redirect them back to the site homepage.

function redirect_user(){
    //...some code...

    //Have tried:
    //if(empty(DOING_AJAX) && $users_role =='somerandomrole') //this works on frontend but allows access to wp-admin
    //if(is_admin() && $users_role =='somerandomrole') //stops access to wp-admin but then frontend stops working
    if((is_admin() || !empty(DOING_AJAX)) && $users_role =='somerandomrole')
    {
         wp_safe_redirect(home_url());
         exit;
    }
 }
 add_action('admin_init', 'redirect_user');

The problem I have is there are dynamic components to our site such as a search tool that makes requests through admin-ajax.php but due to the logic redirects the request (i.e no search results). Is there a way to make this work?

Edit:
Ok so one solution that does seem to work although it doesn’t feel right is:

if($_SERVER['PHP_SELF'] != '/wp-admin/admin-ajax.php' && $users_role =='somerandomrole'){
//...code...
}

Is there a bad side effect to doing it this way?

1 Answer
1

You don’t need to check is_admin because the function is hooked to admin_init, so is_admin() is always true in the callback; that makes that ( is_admin() || !empty(DOING_AJAX) ) always verify as true. You only need to check if the constant DOING_AJAX is not defined or if it is defined and it is false (both cases are not an AJAX request), combined with the user role. For example, to allow AJAX and access only to administrator role:

add_action( 'admin_init', 'redirect_user' );

function redirect_user() {

    $user = wp_get_current_user();

    if( ( !defined('DOING_AJAX') || ! DOING_AJAX ) && ( empty( $user ) || !in_array( "administrator", (array) $user->roles ) ) ) {
        wp_safe_redirect(home_url());
        exit;
    }

}

Also, you can consider to check capabilities instead of roles. For example:

add_action( 'admin_init', 'redirect_user' );

function redirect_user() {

    if( ( !defined('DOING_AJAX') || ! DOING_AJAX ) && ( ! current_user_can('manage_options') ) ) {
        wp_safe_redirect(home_url());
        exit;
    }

}

Leave a Comment