admin管理员组文章数量:1410717
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?
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;
}
}
}
}
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?
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;
}
}
}
}
Share
Improve this question
edited Jun 15, 2020 at 8:21
CommunityBot
1
asked Jan 13, 2020 at 11:03
markbmarkb
2996 silver badges18 bronze badges
11
|
Show 6 more comments
1 Answer
Reset to default 0I 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 );
}
本文标签: phpInfinite loop when logging out using custom login form
版权声明:本文标题:php - Infinite loop when logging out using custom login form 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744838238a2627763.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
mb_page_redirects
in your request workflow? Also at what point and where are you arriving inlogout.php
? – Adam Commented Jan 13, 2020 at 11:24template_redirect
callback you includevalidation-room.php
which then tries to validate the request, but after doing so, you don'texit;
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 inmb_page_redirects
and your logic may be interpreting the condition incorrectly. – Adam Commented Jan 13, 2020 at 11:36