October CMS resources and help articles

Simple and to the point. Optimized by the community.

Re-use and migrate WordPress password hashes in October

by OFFLINE, last modified on February 12th, 2020

This trick describes how you can migrate existing WordPress users to October. It allows a user to log in to the October backend with the same password that was used on WordPress. It will migrate the password to a proper bcrypt hash during the first login.

Step 1: Import user data

Migrate all WordPress password hashes (ẁp_users.user_pass) into the backend_users table. I won't describe in detail how you do this (for example by using Corcel). Just make sure that the wp_users.user_pass column ends up in a new backend_users.wp_password_hash column that you have added manually (or via a proper plugin migration).

The backend_users table should look like this (some columns omitted):

id login password wp_password_hash
1 admin null or random string $1$fDzVfXkk$XY7EKilSen7g8xtVFwyjD.
2 otheruser null or random string $1$Z9NUyZha$OO3qctee2.bZqfnEK3g5J1

Step 2: Install mikemclin/laravel-wp-password

To check a plain text password against a stored WordPress password hash, we can use the mikemclin/laravel-wp-password composer package.

Install it by running composer require "mikemclin/laravel-wp-password" "~2.0.1".

Make sure to run this command from your October root directory, not a plugin's subdirectory. Otherwise you will end up with mixed versions of various Illuminate/* packages.

If you need to add the dependency to a specific plugin make sure it's included in the plugin's composer.json but always run composer install in the root directory.

Step 3: Extend the AuthManager

To extend the default AuthManager class that October uses during the login process, add the following code to a Plugin's Plugin.php file:

use YourVendor\YourPlugin\Classes\AuthManager;

class Plugin extends PluginBase
    public function register()
        App::singleton('backend.auth', function () {
            // This overrides the default AuthManager instance with our own.
            return AuthManager::instance();

Step 4: Override AuthManager methods

There are multiple ways to hook into October's AuthManager. For this use-case, it is enough to override the findUserByCredentials method in our custom AuthManager class.

Create the following class and save it to plugins/your-vendor/your-plugin/classes/AuthManager.php


namespace YourVendor\YourPlugin\Classes;

use Backend\Classes\AuthManager as BackendAuthManager;
use MikeMcLin\WpPassword\Facades\WpPassword;
use October\Rain\Auth\AuthException;

class AuthManager extends BackendAuthManager
    public function findUserByCredentials(array $credentials = [])
        $originalException = null;
        try {
            // Try to log in using the base class' logic. If no exception is thrown,
            // the login worked with the provided credentials.
            // In these case there's nothing for us to do.
            return parent::findUserByCredentials($credentials);
        } catch (AuthException $e) {
            // Capture the thrown exception. We will re-throw it if we are unable
            // to re-hash the user's password.
            $originalException = $e;

        // Find the user by the provided login attribute. 
        // Re-throw the original exception if no user is found.
        $user = $this->findUserByLogin($credentials['login']);
        if ( ! $user) {
            throw $originalException;

        // Check if the user model contains an old wp_password_hash.
        // If not, we have nothing to check against and the login should 
        // fail with the original exception.
        if ( ! $oldHash = $user->wp_password_hash) {
            throw $originalException;

        // Check if the provided password matches the stored WordPress hash
        // using WpPassword's check method.
        // If it does not match, abort by re-throwing the original exception.
        if ( ! WpPassword::check($credentials['password'], $user->wp_password_hash)) {
            throw $originalException;

        // We have found a user where the WordPress hash matched. Let's re-hash the password
        // to bcrypt by setting it on the model (as password and confirmation). 
        // Also remove the old WordPress hash to make sure it is gone for good.
        $user->password = $credentials['password'];
        $user->password_confirmation = $credentials['password'];
        $user->wp_password_hash = '';

        // Return the updated user model. This makes sure the usual 
        // login logic is executed.
        return $user;

Step 5: Test the new AuthManager logic

To test the new AuthManager logic, empty the password column of a user in the backends_user table. Add a WordPress password hash to the wp_password_hash column. You can generate a hash for a specific password using a WordPress Password Hash Generator.

If you log in now, you should notice no changes to the usual login routine. If you check your database after the login the wp_password_hash column should be empty and the password column should contain a valid bcrypt hash.

Make sure to test that subsequent logins with the new hash work as expected.



We use cookies to measure the performance of this website. Do you want to accept these cookies?