wp_set_auth_cookie causes 403 error in the wooCommerce checkout

Long story short: When I programmatically create a user with wp_insert_user and log him in with:

wp_clear_auth_cookie();
clean_user_cache($user-ID);
wp_set_current_user($user-ID, $user-user_login);
wp_set_auth_cookie($user-ID);
update_user_caches($user);

I get a 403 error when reaching woocommerce-Checkout when I want to purchase a test product and can't finish the order process. When I automatically create a user and manually login via default woocommerce login-form it works fine.

Currently testing in a local environment.

Details: I have a custom web-application with its own registration and login. Subscriptions will soon be offered on this platform, for which I would like to use wordrpess with Woocommerce as payment gateways and subscription management - so tried to write sort of a small SSO-Plugin (tried a lot of downloadable plugins before).

The structure is as follows:

my-platform.com/premium

The users log into my-platform.com and with a click on the premium link they get to the Woocommerce environment which is installed in /premium.

Only the checkout is required and displayed. The subscription was previously created in Woocommerce - there is only one for now. For the test, however, I have only created one single purchase product so far.

I want the user to be automatically created and logged in to Wordpress when they visit /premium. (SSO)

For this I use this code as a Wordpress plugin:

function init_sessions() {

  @session_start();

  //check whether the user is logged into the external platform
  if (count($_SESSION)  0  isset($_SESSION['user_id'])) {
    $user = get_user_by('login', $_SESSION['user_email']);

   // create user if not exist in wordpress DB with data from the external platform
   if (!$user  !is_wp_error($user)) {
     $userdata = array(
      'user_pass' = $_SESSION['hashedPasswd'], //will be updated below because wp can only receive unencrypted passwds and the user already has an external hashed password
      'user_email' = $_SESSION['user_email'],
      'user_login' = $_SESSION['user_email'],
      'nickname' = $_SESSION[user_name],
      'role' = 'subscriber');

       $new_user_id = wp_insert_user($userdata);

       //update password with the hashed one from external DB
       //update user-id with the one from the external platform so they always match (wp-registration is deactivated)
       global $wpdb;
       $result = $wpdb-update(
          $wpdb-users,
          array(
            'user_pass' = $_SESSION['hashedPasswd'],
            'ID' = $_SESSION['user_id']
          ),
          array('ID' = $new_user_id));
    }

  // automatically log user in if user exists
  if ($user) {
    wp_clear_auth_cookie();
    clean_user_cache($user-ID);
    wp_set_current_user($user-ID, $user-user_login);
    wp_set_auth_cookie($user-ID);
    update_user_caches($user);
  }
}

  //if user is not logged in external platform, force logout in wordpress aswell
  $currentuser = wp_get_current_user();
  if ($currentuser-ID !== 1) { //prevent log me out as wordpress admin when testing ;-)    
    if (!isset($_SESSION['user_id'])) {
      $token = wp_get_session_token();
      $manager = WP_Session_Tokens::get_instance(get_current_user_id());
      $manager-destroy($token);
      wp_clear_auth_cookie();
    }
  }
}

add_action('init', 'init_sessions');

The login itself works. When I put the test product in the shopping cart and go to the checkout, I cannot complete the purchase and see the following error in the development-console:

POST http://localhost/premium/?wc-ajax=update_order_review
STATUS: 403 Forbidden

And before starting the process I see lots of these errors:

The wordpresspass_2b798aba3a390c97a3136ca1e24fedb3 cookie was rejected because it has already expired.

Caused by these lines:

wp_clear_auth_cookie();
clean_user_cache($user-ID);

I also tried to work with: wp_signon

I installed a SSL-Certificate for my local server and aktivated SSL via Wordpress Plugin so that I can use https but this doesn't solve my problem(s) aswell. The log doesn't show any entries here.

When I login via woocommerce login screen with automatically created user at /premium/my-account, there is no 403 error and I can finish the checkout process.

I'm new to wordpress development and maybe you see something I miss here.

Additional: I later use a webhook woocommerce_payment_complete to tell my platform, that the purchase was successfull:

    function sendHook() {
      @session_start();
      //check if user logged in external platform and SSO to WP was succsessful 
      $sessionVariablesSet = count($_SESSION)  0;
      $sessionUserIDExists = isset($_SESSION['user_id']);
      $userWPloginIsSuccessful = is_user_logged_in();

      if ($sessionVariablesSet  $sessionUserIDExists  $userWPloginIsSuccessful) {
        $user = get_user_by('login', $_SESSION['user_email']);
        if ($user) {
          $args = array(
            'body' = array(
            'request' = 'ajax',
            'userID' = $_SESSION['user_id'],
            'actionToken' = $_SESSION['checkout_action_token']
          )
      );
  wp_safe_remote_post(https://localhost/usersManagementController/setUserSubscription, $args);
        }
      }
    }

    add_action('woocommerce_payment_complete', 'sendHook');

Topic single-sign-on php user-registration users plugins Wordpress

Category Web

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.