Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save rmpel/082fab54ad5ccb08252c83e66fe45079 to your computer and use it in GitHub Desktop.
Save rmpel/082fab54ad5ccb08252c83e66fe45079 to your computer and use it in GitHub Desktop.
Prevent forced re-login on Multi-Domain Multisite in WordPress 6.8 and up
<?php
add_filter( 'password_needs_rehash', 'mu_plugin_mdms_prevent_password_rehashing', 11, 3 );
/**
* Maybe prevent password rehashing, limit rehashing to a set-up time-slot.
* This filter is only effective in WordPress 6.8 and up, and when not overriding the $wp_hasher global variable.
* This is to prevent the password rehashing from happening too often, which WILL cause users forced being logged in every time they switch to a different domain subsite.
*
* @param bool $needs_rehash Whether the password needs rehashing, defaults to true.
* While this could also be false; the way WordPress is set-up,
* this result of `password_needs_rehash`, is always true, at least in a Multi-Domain MultiSite.
* @param string $hash The password hash.
* @param int $user_id The user ID.
*
* @return bool
*/
function mu_plugin_mdms_prevent_password_rehashing( $needs_rehash, $hash, $user_id ) {
if ( ! $needs_rehash ) {
// Already determined that rehashing is not needed, which is the favorable outcome.
// return early.
return false;
}
// Always rehash if the hash does not start with $wp, which is the case for WordPress 6.7.2 and earlier.
// This is an old password hash in a new-hash-setup.
// WordPress already determined that the password needs rehashing, so we allow that to happen.
if ( ! str_starts_with( $hash, '$wp' ) ) {
return $needs_rehash;
}
// Check when the last rehashing was done, we allow rehashing once a day.
$time_slot = gmdate( 'Ymd' ); // Once a day, rehashing is allowed.
// $time_slot = 'w' . gmdate( 'W-Y' ); // Once a week, rehashing is allowed.
// $time_slot = gmdate( 'YmdH' ); // Once per hour, rehashing is allowed.
// This check happens only on log-in, so we do not have to worry about performance.
$last_rehashed = get_user_meta( $user_id, 'wp_core_password_last_rehashed', true );
// Already done this timeslot.
if ( $time_slot === $last_rehashed ) {
// Do not allow rehash.
return false;
}
// At this point, we determined WP wants to rehash, we allow the rehash based on the time-slot not being equal.
// We note the new time-slot in user meta, and allow the rehash to happen.
update_user_meta( $user_id, 'wp_core_password_last_rehashed', $time_slot );
return $needs_rehash;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment