Force Login with Redirect and Exceptions

So in my work, usually for internal company sites, I’ve needed to lock down some sites completely. There are plenty of plugins that accomplish this with varying degrees of success, but I’ve almost always found them to conflict with something or other.

With the code below, we will accomplish three goals:

  1. Forcing users to log on to view the site at all
  2. Redirecting the users back to the page they were originally trying to get to
  3. Creating exceptions for outward facing pages if necessary

Replace http://www.ryanprejean.com with your domain for all examples

Adding this snippet to your functions.php will force all logged off users to be redirected to the login page


function redirect_login_page() {
    if ( ! is_user_logged_in()) {
        wp_redirect( 'http://www.ryanprejean.com/wp-login.php' );
        exit();
    }
}

add_action( 'template_redirect', 'redirect_login_page' );

Now in my case, I didn’t like that users were redirected to their account pages after logging in. I want users to be redirected to the page they were originally trying to get to.

With some slight editing to the function above, we can accomplish this as follows:


function redirect_login_page() {
    $refer=urlencode($_SERVER["REQUEST_URI"]);
    if ( ! is_user_logged_in()) {
        wp_redirect( 'http://www.ryanprejean.com/wp-login.php' . '?redirect_to=' . $refer );
        exit();
    }
}

add_action( 'template_redirect', 'redirect_login_page' );

In my research, I’ve found that WordPress actually listens for the query string ‘?redirect_to=’

So I took advantage of that by appending the referral url to that string.

Now you may have noticed that this won’t help when users directly browse to your login page since the redirect never gets called in the first place. We can remedy this by adding this function:


function redirect_after_login() {
    global $redirect_to;
    if (!isset($_GET['redirect_to'])) {
        $redirect_to = get_option('siteurl');
    }
}
add_action('login_form', 'redirect_after_login');

This function checks for the redirect_to query string and forwards you to your homepage if it’s empty.

Now you may ask, what happens when one user logs off then another tries to log in? The answer is the logoff url gets added to the redirect and you get forwarded right back to the logoff screen. To fix this one, we just specify where users go after logging off:


function redirect_login(){
  wp_redirect( 'http://www.ryanprejean.com/wp-login.php' );
  exit();
}
add_action('wp_logout','redirect_login');

Exceptions:
For one of my websites that was locked down, I needed a way to establish pages accessible to clients that didn’t force a log in. For example, an invitation form to send to clients. I opted to create a page called external, and make it the parent of all exempted pages. My permalinks are set to post name, so that puts ‘external’ in every url of my exempted pages. I then edited my force log in function:


function redirect_login_page() {
    $refer=urlencode($_SERVER["REQUEST_URI"]);
    $isItExt = strpos(strtok($_SERVER["REQUEST_URI"],'?'), 'external');
    if ( ! is_user_logged_in() && $isItExt==false) {
        wp_redirect( 'http://www.ryanprejean.com/wp-login.php' . '?redirect_to=' . $refer );
        exit();
    }
}
add_action( 'template_redirect', 'redirect_login_page' );

This function checks for the string ‘external’ in the url and bypasses the force login function if it exists. Notably, my function strips away query strings for this check so that it cannot be bypassed by typing something like http://www.ryanprejean.com/secrets/?external in the address bar.

In Conclusion:
If you didn’t care about following all that, then here’s a summary of all functions to be added to functions.php to achieve the stated goals:


function redirect_login_page() {
    $refer=urlencode($_SERVER["REQUEST_URI"]);
    $isItExt = strpos(strtok($_SERVER["REQUEST_URI"],'?'), 'external');
    if ( ! is_user_logged_in() && $isItExt==false) {
        wp_redirect( 'http://www.ryanprejean.com/wp-login.php' . '?redirect_to=' . $refer );
        exit();
    }
}
add_action( 'template_redirect', 'redirect_login_page' );

function redirect_after_login() {
    global $redirect_to;
    if (!isset($_GET['redirect_to'])) {
        $redirect_to = get_option('siteurl');
    }
}
add_action('login_form', 'redirect_after_login');

function redirect_login(){
  wp_redirect( 'http://www.ryanprejean.com/wp-login.php' );
  exit();
}
add_action('wp_logout','redirect_login');