Ajax login and nonce verification

Hi all,

I am trying to achieve the following –

1. I have a custom form “X” which requires login to submit.
2. I also have a ajax login form.

Workflow –
1. When a not logged in user comes to the custom form “X”, he/she fill up the form and when trying to submit, ajax login popup opens and user login via that ajax login form. After that, they can submit the form “X”.

Issue –
I am using nonce for form “X” which generates a nonce value for not logged in users. But after the ajax login is done, the nonce value requires to be updated. I am generating a new nonce after login is done. But that nonce is also not working and form “X” cannot be nonce verified.

Code of form “X” –


<form name="x" action="<?php echo esc_url( admin_url('admin-post.php') ); ?>" method="post">
      <label for="checkbox_one"><?php echo esc_html__("Checkbox Name", "text-domain"); ?></label>
      <input type="checkbox" name="checkbox_one" id="checkbox_one" >
      <input type="hidden" name="action" value="my_action">
      <?php wp_nonce_field( "action_name", "nonce_name" ); ?>
      <input type="submit" value="Submit">
</form>
<a href="#"><?php echo esc_html__("Click me to login first. An ajax login modal will open.", "text-domain"); ?></a>

Code of ajax login submission handle via admin-ajax.php


function login(){
        
        //bail early if found suspecious with nonce verification.
	if ( !isset( $this->values['_login_nonce'] ) || ! wp_verify_nonce( $this->values['_login_nonce'], 'ajax_login' ) ) {
        
            wp_send_json_error([
                'login'     => false,
                'message'   => esc_html__('Security check unsuccessful.','text-domain')
            ]);
        
        }

        if( isset($this->values['_username']) && isset($this->values['_password']) ){

            $creds = array(
                'user_login'    => sanitize_user($this->values['_username']),
                'user_password' => $this->values['_password'],
                'remember'      => true
            );
         
            $user = wp_signon( $creds, false );
         
            if ( is_wp_error( $user ) ) {
                wp_send_json_error([
                    'login'     => false,
                    'message'   => esc_html($user->get_error_message())
                ]);
            }else{
                wp_set_current_user($user->ID);
                wp_set_auth_cookie($user->ID);
                wp_send_json_success([
                    'login'     => true,
                    'message'   => esc_html__('Login Successful.', 'text-domain'),
                    'new_nonce' => wp_create_nonce('action_name'),
                ]);
            }
            
        }

        exit();
}

You can see that after successful login via ajax form, I am again creating the nonce with same nonce action of form “X” which is wp_create_nonce('action_name') which I intend to inject in the form “X” after login is done.

But unfortunately, this nonce is not working when I am trying to authenticate form “X” submission after the ajax login. I checked the browser and found the nonce is different. I will appreciate any help form the community here.

Thanks!



Source link