Created
July 18, 2025 06:59
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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