在测试和阅读WordPress的代码后。下面是对这种现象的解释。首先,以下是nonce解释以及它将如何影响流程。根据WordPress Nonces,
nonce是一个“一次使用的数字”,用于帮助保护URL和表单免受某些类型的恶意或其他滥用。WordPress nonce不是数字,而是由数字和字母组成的散列。它们也不是只使用一次,而是有一个有限的“寿命”,在这之后它们就会过期。在这段时间内,将为给定上下文中的给定用户生成相同的nonce。该操作的nonce对于该用户将保持不变,直到该nonce生命周期完成。
简而言之,出于安全原因,它是一个检查参考,以确保内容不被篡改。
来到登录案例。您的登录逻辑是正确的。表单+表单处理程序。登录过程:
输入用户名密码后单击登录,它将自己提交到同一页面,页面似乎已刷新,出现注销链接,注销链接由生成wp_logout_url() (默认模板),在这个模板中,nonce是一起生成的,您可以参考源代码了解详细信息因为nonce是基于一些东西,包括时间引用和cookie值。如果您按照1-3顺序操作,并在此时单击注销。它将要求您提供确认页面但是,如果立即尝试,请转到URL栏,单击enter以强制加载页面,就像输入新的URL一样。然后,如果再次单击“注销”。它不要求确认。它会提示确认框,因为它认为注销时间无效。
这是因为cookie值尚未与值一起使用Null. 因此,nonce无效。
Once the cookies have been set, they can be accessed on the next page load with the $_COOKIE or $HTTP_COOKIE_VARS arrays.
^^^^^^^^^^^^^^
您可以参考此
related post 和
php manual on cookie所以有一个解决方案,WordPress登录也使用但没有记录(可能有记录,但我还没有读过),添加一个“重定向”参数来处理这个问题。通过使用重定向,它将是一个新的页面加载,因此cookie将被更新,因此nonce是有效的。
所以,这里有一个解决方案:
登录表格
<form method="post" action="<?= get_permalink(); ?>">
<p><input type="text" name="my_username" placeholder="Username" /></p>
<p><input type="password" name="my_password" placeholder="Password" /></p>
<p><input type="submit" name="submit" value="Login" /></p>
<!-- change to your url -->
<input type="hidden" name="redirect_to" value="somewhere_or_same_link" />
</form>
表单处理程序
add_action(\'after_setup_theme\', \'my_login\');
function my_login()
{
if(!empty($_POST[\'my_username\']) && !empty($_POST[\'my_password\']))
{
$user = wp_signon([
\'user_login\' => $_POST[\'my_username\'],
\'user_password\' => $_POST[\'my_password\'],
\'remember\' => true],
is_ssl());
if(is_wp_error($user))
{
echo $user->get_error_message();
}
else
{
if ( ! empty( $_POST[\'redirect_to\'] ) ) {
wp_set_current_user($user->ID);
$redirect_to = wp_unslash( $_POST[\'redirect_to\'] );
wp_safe_redirect( $redirect_to );
// or directly use wp_redirect( $redirect_to );
}
exit(); // it is important to exit the current script so that the redirect start a new one completely or it will remain the same, the cookie will not be refreshed
}
}
}