使用自定义登录表单注销时出现无限循环

时间:2020-01-13 作者:markb

我有一个基于我创建的父主题使用的子主题。父主题使用标准wp_login_form 虽然此子主题使用仅用户名选项(站点本身是本地的,而不是面向internet的,并且是IP锁定的)。

本质上,我有一个登录表单,您可以从下拉列表中选择用户,然后提交它来检查一些验证以进行身份验证。如果我清除浏览器缓存和cookie并访问该网站,我会看到表单。我可以登录,然后使用该网站没有问题。当我注销时,它会转到我的自定义注销页面,然后在home_urlhome_url(\'/login/)`

它没有在网络中的任何其他站点(多站点)上造成任何问题,但如果我将登录恢复到父主题页面,则不会出现循环。

我想知道我是否在代码中遗漏了什么,或者是否有另一种内置的登录方式,而无需“登录”;“密码”;只是一个下拉列表?

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

Code零六
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;
            }
        }
    }
}

1 个回复
SO网友:Adam

在回顾了您的逻辑/评论之后,我在这里进行推测,但让我们尝试以下内容

Possible issue:

在登录期间,虽然您正在设置身份验证cookie,但您没有设置当前用户,这可能是导致注销时出现故障的原因is_user_logged_in 返回假阳性/阴性结果。

Possible resolution:

在您的validation-room.php 给…打个电话wp_set_current_user, 与输入回拨时一样mb_page_redirectstemplate_redirect 胡克,你所依赖的is_user_logged_in 要正常工作,它本身会检查global $current_user 变量

引擎盖下is_user_logged_in 呼叫wp_get_current_user 哪个呼叫_wp_get_current_user 触发过滤器determine_current_user 这需要两次内部回调wp_validate_auth_cookiewp_validate_logged_in_cookie.

最初的不正确验证和随后对wp_logoutwp_set_current_user 不知何故引起了一个问题。

$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 );
}