使用 ajax 的 Wordpress 登录/注销。 Nonce 问题,在第二次 ajax 调用时,给出 403 错误

问题描述 投票:0回答:0

我尝试在我的网站上为用户进行 ajax 登录/注销和注册。 通过ajax登录有效。 ajax 响应给出注销的 html 代码和一个新的随机数,在用户登录后生成。当我尝试注销而不重新加载页面时,出现 403 错误。新的随机数不通过 check_ajax_referer()。 如果我重新加载页面,我可以注销。 注销调用的 ajax 响应给出了登录的 html 和一个新的随机数。当我尝试在不重新加载页面的情况下登录时,出现 403 错误。新的 nonce 不会再次通过 check_ajax_referer()。 如果我重新加载页面,我可以登录。

我阅读了很多与此主题相关的帖子,但我找到了为什么我的代码不起作用。

起初,我对登录和注销随机数使用相同的“操作”(ajax_nonce_control)。 我尝试将登录随机数和注销随机数分开。所以现在我有使用“ajax_nonce_login”操作创建的登录随机数和使用“ajax_nonce_logout”操作创建的注销随机数。

但这与我在用户登录或注销后生成的新闻随机数相同,并通过 ajax 响应传递未能通过 check_ajax_referer()。

这是我的代码:

在我的 functions.php 文件中

<?php
/*** add scripts and styles */
add_action('wp_enqueue_scripts', 'wpdocs_theme_name_scripts');
function wpdocs_theme_name_scripts() {
    
    wp_enqueue_script('script', get_template_directory_uri() . '/js/script.js', array(), '1.0.1', true);
    $nonce = (wpmem_user_has_role( 'pro' ))? 'ajax_nonce_logout' : 'ajax_nonce_login' ;
    wp_localize_script('script', 'ajax_var', array(
         'url' => admin_url('admin-ajax.php'),
         'nonce' => wp_create_nonce($nonce)
     ));


}




// Execute the action only if the user isn't logged in
if ( ! is_user_logged_in() ) {
    add_action( 'init', 'ajax_login_init' );
}
/*** Enable the user with no privileges to run ajax_login() in AJAX */
function ajax_login_init(){
    add_action( 'wp_ajax_nopriv_ajaxlogin', 'ajax_login' );
    do_action('qm/debug','ajax_login_init');
}
/*** login the user */
function ajax_login(){
    // First check the nonce, if it fails the function will break
    check_ajax_referer( 'ajax_nonce_login', 'security' );
    // 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 ) ) {
    wp_send_json_error( __( 'Wrong username or password.', 'mmh2022' ) );
    } else {
    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();
    get_template_part('content', 'pro_profile');
    $html = ob_get_clean();
    wp_send_json_success( array('html' => $html, 'nonce' => wp_create_nonce('ajax_nonce_logout')) );
    }
    wp_die();
}

// Execute the action only if the user is logged in
if ( is_user_logged_in()) {
    add_action( 'init', 'ajax_logout_init' );
}
/*** Enable the user with privileges to run ajax_logout() in AJAX */
function ajax_logout_init(){
    add_action( 'wp_ajax_ajaxlogout', 'ajax_logout' );
    do_action('qm/debug','ajax_logout_init');
}
/*** logout the user */
function ajax_logout(){
    // First check the nonce, if it fails the function will break
    check_ajax_referer( 'ajax_nonce_logout', 'security' );
    // Nonce is checked, get the POST data and sign user on
    wp_logout();
    wp_set_current_user(0);
    
    ob_start();
    get_template_part('content', 'pro_login');
    $html = ob_get_clean();
    wp_send_json_success( array('html' => $html, 'nonce' => wp_create_nonce('ajax_nonce_login')) );
    wp_die();
}

?>

在我的 script.js 文件中


let loginButton = document.getElementById("login-button");
if(loginButton){
    loginButton.addEventListener('click', login_user);
}
let logoutButton = document.getElementById("logout-button");
if(logoutButton){
    logoutButton.addEventListener('click', logout_user);
}


let the_nonce = ajax_var.nonce;

function logout_user (Event){
    let proContent = document.getElementById("pro-content");
    Event.preventDefault();

    
    //append the field
    var formData = new FormData();
    formData.append('action', 'ajaxlogout');
    formData.append('security', the_nonce );

    //send
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            const ajax_response = JSON.parse(this.response);
            proContent.innerHTML = ajax_response.data.html;
            
                        let loginButton = document.getElementById("login-button");
            the_nonce = ajax_response.data.nonce;
            if(loginButton){
                loginButton.addEventListener('click', login_user);
            }
        }
    };
    xhttp.open("POST", ajax_var.url, true);
    xhttp.send(formData);
}

function login_user (Event){
    let proContent = document.getElementById("pro-content");
    let loginMail = document.getElementById("login-mail");
    let loginPwd = document.getElementById("login-pwd");
    var error = false;
    Event.preventDefault();
    
    //append field
    var formData = new FormData();
    formData.append('action', 'ajaxlogin');
    if(validateEmail(loginMail) ){
        formData.append('username', loginMail.value);
    }else{
        error = true;
    }
    if(loginPwd.value){
        formData.append('password', loginPwd.value);
    }else{
        error = true;
    }
    formData.append('security', the_nonce);
    
    //send
    if(!error){
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                const ajax_response = JSON.parse(this.response);
                proContent.innerHTML = ajax_response.data.html;
                let logoutButton = document.getElementById("logout-button");;
                the_nonce = ajax_response.data.nonce;
                console.log('li the_nonce ' + the_nonce);
                if(logoutButton){
                    logoutButton.addEventListener('click', logout_user);
                }
            }
        };
        xhttp.open("POST", ajax_var.url , true);
        xhttp.send(formData);
    }
}

我想我做错了什么,但我能弄清楚哪里…… 任何帮助都会很棒!!

ajax wordpress authentication nonce
© www.soinside.com 2019 - 2024. All rights reserved.