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