0

I have a child theme that I'm using based on a parent theme I created. The parent theme uses the standard wp_login_form while this child theme uses a username only option (the site itself is local - not internet facing - and is IP locked).

Essentially I have a login form that you select the user from the dropdown and then submit which checks some validations to authenticate. If I clear the browser cache and cookies and go to the site I see the form. I can log in, and then use the site no problem. When I log out, it goes to my custom logout page but then loops between home_url and home_url('/login/)`

It hasn't caused any issues on any of the other sites in the network (multisite), but if I revert the login to the parent theme page there is no loop.

I was wondering if I was missing something in the code - or if there was another builtin way of logging in without a "password" and just a drop down?

enter image description here


Code

login.php

// build the form
$mb_login_args = [
    'role__not_in'  => [ 'site_owner', 'viewer_user', 'administrator' ]
];

// get the users
$mb_users = get_users( $mb_login_args );

echo '<form id="mbform" method="post">';
    echo '<p class="login-username">';
        echo '<label for="mb_login_username">Select resource</label>';
        echo '<select name="log" id="mb_login_username">';
                echo '<option value="">Select a room</option>';
                // loop users
                foreach( $mb_users as $mb_user ) {
                    echo '<option value="' . $mb_user->user_login . '">' . $mb_user->display_name . '</option>';
                }
        echo '</select>';
    echo '</p>';

    echo '<p class="login-submit">';
        echo '<input type="submit" name="wp-submit" id="mb_login_submit" class="button button-primary" value="Save resource">';
        echo '<input type="hidden" name="pwd" value="{mb_login_password}">';
        wp_nonce_field( 'mb_action_login', 'mb_field_login' );
    echo '</p>';
echo '</form>';

functions.php

add_action( 'template_redirect', function() {
    if( is_page('login') && !is_user_logged_in() ) {
        include_once locate_template( '/_mbcore/validation-room.php' );
    }
});

validation-room.php

$mb_field_room  = ( isset( $_POST[ 'mb_field_login' ] ) ? $_POST['mb_field_login'] : null );
if( $mb_field_room || wp_verify_nonce( $mb_field_room, 'mb_action_login' ) || !empty($mb_field_room) ) {
    $mb_meeting_log = isset($_POST['log'])  ? $_POST['log'] : null;
    $mb_meeting_pwd = isset($_POST['pwd']) && $_POST['pwd'] == '{mb_login_password}' ? 'password' : null;
// other validation here
    // on success
    wp_set_auth_cookie( get_user_by('login', $mb_meeting_log)->ID, true, true );
}

logout.php

// do some checking here for $_GET['mblock'] and if valid number
// then in a switch statement 

    case 88:
        // log out the user
        wp_logout();

        // set the user ID to 0
        wp_set_current_user(0);

        // redirect user
        // $wp_logout_url = home_url('wp-login.php?action=logout&_wpnonce=' . wp_create_nonce('log-out') );
        wp_safe_redirect( $wp_logout_url );
        break;

parent theme: functions.php

function mb_page_redirects() {

    // authenticated users
    if( is_user_logged_in() )  {

        // setup: incomplete
        if( get_option('mb_theme_setup') === 'true' ) {

            // direct the valid user
            // mb_is_admin() checks custom caps
            if( mb_is_admin() ) {

                if( !is_page('setup') ) {
                    wp_safe_redirect( home_url('/admin/setup/') );
                    exit;
                }

            // otherwise log the user out
            } else {
                wp_safe_redirect( home_url('/admin/logout/') );
                exit;
            }

        // setup: complete
        } else {

            if( mb_is_admin() ) {

                // send admin to the config panel
                if( is_page( array('login', 'pw', 'setup') ) ) {
                    wp_safe_redirect( home_url('/admin/') );
                    exit;
                }

            // non-administrator redirects
            } else {

                // send admin to the front
                if( is_page( array('admin', 'setup', 'login', 'pw') ) ) {
                    wp_safe_redirect( home_url() );
                    exit;
                }
            }
        }

    // non-authenticated users
    } else {

        // check the setting for authentication bypass
        // empty or false means we need to log in
        if( get_option('mb_setting_auth_bypass') == 'true' ) {

            if( is_page( array('login', 'pw') ) ) {
                wp_safe_redirect( home_url() );
                exit;
            }

        } else {

            // force users to the login screen
            if( !is_page('login') ) {
                wp_safe_redirect( home_url('/admin/login/') );
                exit;
            }
        }
    }
}
11
  • Where are you calling mb_page_redirects in your request workflow? Also at what point and where are you arriving in logout.php?
    – Adam
    Jan 13, 2020 at 11:24
  • @Adam from a plug-in i made that applies to all the themes. they all use the same structure: login, logout, admin, front, password, taxonomy, setup
    – markb
    Jan 13, 2020 at 11:26
  • I'm trying to work out your auth workflow, not sure I've grokked it yet but in your template_redirect callback you include validation-room.php which then tries to validate the request, but after doing so, you don't exit; to kill the request which means the request falls through to the page you're posting to (as you are neither doing a redirect) this may keep the user on the same URI (path) which gets processed future in mb_page_redirects and your logic may be interpreting the condition incorrectly.
    – Adam
    Jan 13, 2020 at 11:36
  • @Adam i knew i forgot something! so the form is called via ajax and then it has a die at the end when successfully set. if you see that gif the banner goes green
    – markb
    Jan 13, 2020 at 11:38
  • Ok cool, so did that solve the issue for you or is that only an additional detail?
    – Adam
    Jan 13, 2020 at 11:40

1 Answer 1

0

I am speculating here after reviewing your logic/comments above, yet let's try as follows

Possible issue:

During login, although you are setting the auth cookie, you are not setting the current user and this is potentially the cause of the break-down upon logout due to is_user_logged_in returning a false-positive/negative result.

Possible resolution:

In your validation-room.php add a call to wp_set_current_user, as when entering your callback mb_page_redirects on the template_redirect hook, you are relying on is_user_logged_in to function correctly, which itself checks the state of the global $current_user variable.

Under the hood is_user_logged_in calls wp_get_current_user which calls _wp_get_current_user which fires a filter determine_current_user that calls two internal callbacks wp_validate_auth_cookie and wp_validate_logged_in_cookie.

It is possible that the initial improper validation and later subsequent calls to wp_logout and wp_set_current_user are somehow causing an issue.

$mb_field_room  = ( isset( $_POST[ 'mb_field_login' ] ) ? $_POST['mb_field_login'] : null );

if( $mb_field_room || wp_verify_nonce( $mb_field_room, 'mb_action_login' ) || !empty($mb_field_room) ) {
    $mb_meeting_log = isset($_POST['log'])  ? $_POST['log'] : null;
    $mb_meeting_pwd = isset($_POST['pwd']) && $_POST['pwd'] == '{mb_login_password}' ? 'password' : null;

    $user = get_user_by('login', $mb_meeting_log);

    wp_clear_auth_cookie(); // let's be sure about it...
    wp_set_auth_cookie( $user->ID, true, true );
    wp_set_current_user( $user->ID, $user->user_login );
}
1
  • as hopeful as I was it didn't resolve it. I think you are on the right track though, as if I log into the site and then log out (into the loop) it doesn't trash the cookies/authentication from other sites unlike when logging in it allows access to all of them
    – markb
    Jan 15, 2020 at 4:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.