AJAX登录和注销的WordPress随机数问题

时间:2014-12-05 作者:stoi2m1

我正在使用ajax提交登录和注销凭据。登录和注销表单将替换为成功响应返回的html。没有页面加载成功登录或注销后,页面内容通过ajax get请求加载。

我可以成功登录然后注销,但当我第二次尝试登录时,我收到check\\u admin\\u referer()发出的暂时失败(-1)。我已经验证了在第二次登录期间发送的nonce与第一次提交时不同,但据我所知,nonce是这样的。在注销过程中,此nonce被发送回ajax请求。

我是否过度考虑了在会话或全局变量中刷新或存储某些内容的需要?我的代码在第一次尝试登录和注销时工作。在这里共享我的代码可能没有好处。

有人知道为什么我收到的临时通知无效吗?

EDITS BELOW

请看我的代码,它是php和javascript的混合体

<?php
/* the php sidebar menu for a logged in user
 * this is also fetched by the ajax log in action
 */
function not_logged_in_menu() { ?>

    <div class="login-form">
        <h2>Login</h2>

        <form method="post" action="<?php site_url(); ?>/wp-login.php" class="wp-user-form">
            <div class="input-login">
                <div class="loader"></div>
                <input type="submit" class="login ui-btn" name="Login" value="Login" />
                <span class="gzp-icon-login"></span>
            </div>
            <div class="input-prepend">
                <span class="add-on icon-username"></span>
                <input type="text" name="log" value="" class="input-medium" id="user_login" placeholder="Username" />
            </div>
            <?php /*<br class="clearer" />*/ ?>
            <div class="input-prepend">
                <span class="add-on icon-password"></span>
                <input type="password" name="pwd" value="" id="user_pass" class="input-medium" placeholder="Password" />
            </div>
            <?php wp_nonce_field( \'ajax-login-nonce\', \'security\' ); ?>                  
        </form>
    </div> <?php
}

/* the php sidebar menu for a logged out user
 * this is also fetched by the ajax log out action
 */
function logged_in_menu() {
        global $user_identity; ?>

    <div class="login-form">
        <h2 class="welcome">Welcome<br /><?php echo $user_identity; ?></h2>

        <a href="<?php echo wp_logout_url( home_url() ); ?>" id="logout" class="btn btn-inverse" title="Logout">Logout</a>
        <div class="loader"></div>
        <div class="clearer"></div>
    </div> <?php
}

/* the php login ajax action */
function ajax_login(){

        check_ajax_referer( \'ajax-login-nonce\', \'security\' ); // on the second log in attempt with no page refresh this
                                                              // function fails her

        // Nonce is checked, get the POST data and sign user on
        $info = array();
        $info[\'user_login\'] = $_POST[\'username\'];
        $info[\'user_password\'] = $_POST[\'password\'];
        $info[\'remember\'] = true;

        $user = wp_signon( $info, false );

        if ( is_wp_error($user) ){
                echo json_encode(array(\'loggedin\'=>false, \'message\'=>__(\'Wrong username or password.\')));
                die();
        }

        //setting the user variables so the globals have content without an actual page load
        wp_set_current_user( $user->ID, $user->user_login );
        wp_set_auth_cookie( $user->ID, true, false );
        do_action( \'wp_login\', $user->user_login );

        ob_start();
        gzp_logged_in_menu();
        $menu_content = ob_get_contents();
        ob_end_clean();

        echo json_encode(array(\'loggedin\'=>true, \'message\'=>__(\'Login successful, redirecting...\'), \'menu_content\'=>$menu_content,\'user_signon\'=>$user));

        die();
}
add_action( \'wp_ajax_nopriv_ajaxlogin\', \'ajax_login\' );


/* the php log out ajax action */
function ajax_logout(){

        // First check the nonce, if it fails the function will break
        wp_verify_nonce( $_POST[\'security\'], \'log-out\' );

        wp_logout();

        ob_start();
        gzp_not_logged_in_menu();
        $menu_content = ob_get_contents();
        ob_end_clean();

        echo json_encode(array(\'loggedout\'=>true, \'message\'=>__(\'Logout successful, redirecting...\'), \'menu_content\'=>$menu_content));

        die();
}
add_action( \'wp_ajax_ajaxlogout\', \'ajax_logout\' );
?>


<script type="text/javascript">
/* javascripted loaded in the head of page on page load */
jQuery(document).ready(function(event) {
        admin_bar_login();
        admin_bar_logout();
});    
/* the ajax post for a log in attempt */
function admin_bar_login() {
        /* login action */
        jQuery(\'form.wp-user-form\').on(\'submit\', function(e) {
                e.preventDefault();

                jQuery(\'.login-form input.login\').parent(\'.input-login\').addClass(\'loading\').show();
                console.log(jQuery(\'form.wp-user-form #security\').val());
                jQuery.ajax({
                        type: \'POST\',
                        dataType: \'json\',
                        url: ajaxurl,
                        data: {
                                \'action\': \'ajaxlogin\', //calls wp_ajax_nopriv_ajaxlogin
                                \'username\': jQuery(\'form.wp-user-form #user_login\').val(),
                                \'password\': jQuery(\'form.wp-user-form #user_pass\').val(),
                                \'security\': jQuery(\'form.wp-user-form #security\').val()
                        },
                        success: function(data){
                                if (data.loggedin == true){
                                        jQuery(\'.navigation-right .menu\').html(data.menu_content);
                                        AAPL_loadPage(document.location.toString(),1); //refresh the #content of the page
                                        admin_bar_logout(); //this adds the event handler to the log out content just added
                                        jQuery.bootstrapGrowl(data.message);
                                }
                                else if(data.loggedin == false) {
                                        jQuery(\'.login-form input.login\').parent(\'.input-login\').removeClass(\'loading\');
                                        jQuery.bootstrapGrowl(data.message);
                                }
                        },
                        fail: function(data){
                                if(data.loggedin == \'false\')
                                        jQuery.bootstrapGrowl(data.message);
                        }
                });                                            
        });
}
/* the ajax post for a log out attempt */
function admin_bar_logout() {
        //logout action
        jQuery(\'#logout\').on(\'click\', function(e) {
                e.preventDefault();

                jQuery(this).parent(\'.login-form\').addClass(\'loading\').show();
                var href = jQuery(this).attr(\'href\'),
                    vars = href.split("&"),
                    wp_nonce = \'_wpnonce\',
                    security = \'\';

                for (var i=0;i<vars.length;i++) {
                           var pair = vars[i].split("=");
                           if(pair[0] == wp_nonce){security = pair[1];}
                }

                jQuery.ajax({
                        type: \'POST\',
                        dataType: \'json\',
                        url: ajaxurl,
                        data: {
                                \'action\': \'ajaxlogout\', //calls wp_ajax_ajaxlogout
                                \'security\': security,
                        },
                        success: function(data){
                                if (data.loggedout == true){
                                        jQuery(\'.navigation-right .menu\').html(data.menu_content);
                                        AAPL_loadPage(document.location.toString(),1); //refresh the #content of the page
                                        admin_bar_login(); //this adds the event handler to the log in content just added
                                        jQuery.bootstrapGrowl(data.message);
                                }
                                else if(data.loggedin == false) {
                                        jQuery(\'.login-form input.login\').parent(\'.input-login\').removeClass(\'loading\');
                                        jQuery.bootstrapGrowl(data.message);
                                }
                        },
                        fail: function(data){
                                if(data.loggedin == \'false\')
                                        jQuery.bootstrapGrowl(data.message);
                        }
                });                                            
        });
}
</script>

Solution Below

下面标记了我的问题的正确答案,但我还有另一个问题,我的用户实际上没有注销。返回的nonce是登录的nonce。当我尝试以匿名用户身份重新登录时,nonce对无效wp_verify_nonce().

我发现wp_logout() 在我的情况下,仅仅注销是不够的。这个$current_user 变量仍然保留所有用户数据,并且is_user_logged_in() 返回true。直到我wp_set_current_user(0) 我是否看到用户实际上已注销。

我还消除了在登录期间使用nonce的需要。

有关该主题的讨论,请参阅此帖子

wp_logout Not Logging Me Out

2 个回复
最合适的回答,由SO网友:Rarst 整理而成

我没有运行您的代码,但我有根据地猜测,您的代码流中的错误在于nonce是特定于用户的。虽然匿名nonce是可能的,但它对于其用途是无用的,因为它对于所有匿名用户都是相同的。

所以可能存在不匹配的地方,您试图使用特定用户的nonce,同时保持匿名。

SO网友:NoBugs

另一件需要考虑的事情是,wp nonce系统同时使用当前用户id和sessiontoken(wordpress\\u logged\\u in\\uuu…cookie)。

如果查看wp\\u verify\\u nonce函数源,您将看到它将nonce与哈希进行比较(当前和最后12小时期间+“|”+操作+“|”+当前用户id+“|”+会话肯)

这些变量的任何更改都会使哈希不匹配。

结束

相关推荐

Scrolling Posts with Ajax

这是整个谷歌都面临的一个非常普遍的问题,但我们处理这一问题的方式之间存在冲突。我使用本教程http://code.tutsplus.com/articles/getting-loopy-ajax-powered-loops-with-jquery-and-wordpress--wp-23232我不得不说,这是互联网上解释得最好的教程(对我来说)。到目前为止,我的工作做得很好,但也有一些例外,因为我缺乏知识,所以很难将其应用于我的网站。一些例外。如果只有一个post,那么停止加载其他条件的作者,我可以从页面