# How do I move WordPress users to Supabase authentication?

> Export your WordPress users with their existing password hashes, not plain text, then load them into Supabase and verify the old hash format on first login so no one has to reset. WordPress uses phpass hashes, which Supabase can validate with a custom check, after which it rehashes to its own format. The export also needs emails, roles, and IDs to keep relationships intact. WPBuildAI exports the user table to a clean, Supabase-ready format so members keep their logins.

Source: https://wpbuildai.com/connect-wordpress-users-supabase-authentication-export/
By lawrence-arya · 2026-06-14

---
To connect WordPress users to Supabase authentication without forcing a mass password reset, you migrate the password hashes, not the passwords. WordPress stores each password as a phpass hash, and Supabase can be configured to verify that old hash the first time a member logs in, then quietly rehash to its own format. Around that, you export emails, usernames, roles, and the user IDs so the rest of each account stays intact. WPBuildAI exports the user table to a clean, Supabase-ready format, so members keep their logins through the move.

Target the right Postgres major version before you move password hashes: Supabase logged [self-hosted instances upgrading from Postgres 15 to 17 as a breaking change on 18 May 2026](https://supabase.com/changelog), and auth tables are the last place you want a surprise during a cutover.

## Why forcing a reset is the wrong default

The lazy version of this migration emails everyone a reset link, and it bleeds members. Every extra step between a user and their account is a place to lose them, the same friction effect Baymard documents in its [cart abandonment research](https://baymard.com/lists/cart-abandonment-rate), where added steps in a flow sharply increase drop-off. A forced reset is exactly that kind of added step, applied to your entire member base at once: every active user must check email, click a link, and choose a new password just to keep access they already had. A meaningful fraction never complete it, and you have turned a behind-the-scenes migration into visible churn. Migrating the hashes keeps the login invisible to the user, who signs in as normal and never knows the backend changed, which is the whole point of doing it well.

## Migrate the hashes, not the passwords

The key fact that makes a seamless migration possible is that WordPress never stores the actual passwords, only one-way hashes of them, and you migrate those hashes. A hash cannot be reversed into the password, so moving it exposes nothing, and it is exactly what you need to verify a login later: when the user types their password, you hash the input and compare it to the stored hash. OWASP's [Password Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html) describes this model and why migrating existing hashes, then upgrading them on next login, is the standard way to move between systems without weakening security or disrupting users. So the unit of migration is the hash, never a password, and that single fact is what lets members keep logging in with the credentials they already have.

## How the hash migration works

1. **Export users** with their phpass hashes, emails, usernames, roles, and IDs.
2. **Load them into Supabase**, storing the legacy hash alongside each user record.
3. **Verify on first login**: when a migrated user signs in, check the password against the stored phpass hash; if it matches, authenticate them.
4. **Rehash going forward**: on that successful login, let Supabase compute and store its own modern hash, so the legacy hash is used only once per user.
5. **Preserve the IDs**, so related tables still resolve to the right user.

Done this way, the first login per user transparently upgrades them from the old hash to Supabase's format, and every login after is native. The 2024 [Web Almanac](https://almanac.httparchive.org/en/2024/) shows how widely sites run authentication layers and how much account data sits behind them, which is exactly the data a careless migration strands.

## Why phpass needs a custom verifier

The one technical wrinkle is that WordPress's phpass hashes are not the format Supabase uses by default, so a plain import will not validate them. phpass is its own scheme (a portable hashing format with its own prefix and iteration encoding), while modern systems favour bcrypt or argon2. That mismatch is why you need a custom verification step at first login: a small function that recognises a legacy phpass hash, validates the entered password against it using the phpass algorithm, and, on success, hands the password to Supabase to rehash in its own scheme. After that one login, the user has a native hash and the verifier is never needed for them again. This is the standard "verify-then-upgrade" pattern OWASP describes, and it is what bridges the two hashing formats without asking users to reset, rather than a limitation that forces a reset.

## A worked example: a membership site moved

Picture a membership site with 5,000 users moving off WordPress. The team exports the users, each with their phpass hash, email, role (member, admin), and WordPress user ID, and loads them into Supabase with the legacy hash stored per user. They add a first-login verifier that checks entered passwords against the phpass hashes and rehashes on success. At launch, members visit the new site, log in with their usual password, and are authenticated against the legacy hash, then silently upgraded to Supabase's format, no reset, no email, no friction. Because the user IDs were preserved, each member's order history and posts still resolve to their account. Over the following weeks, as members log in, the legacy hashes are progressively replaced with native ones. The migration was invisible to 5,000 people, which is the success condition, contrasted with the reset-everyone approach that would have lost a chunk of them.

## Keep the relationships, not just the logins

A login that works on an account with no history attached is only half a migration. Other tables reference the user by ID, orders, authored posts, comments, membership records, so keeping the original user IDs is what preserves those relationships on the new system. Export email, username, display name, roles or capabilities, the user ID, and any profile or membership fields you depend on, not just the email and hash. If you drop the IDs and let the new system assign fresh ones, the login may work while the user's order history and content point at nothing, which is a broken account from the member's perspective even though they can sign in. This is the user-table version of the same care covered in [migrating a WordPress database to Supabase](/migrate-wordpress-sql-database-to-supabase-ai-website-builder-app/) and [exporting WordPress data for a Supabase backend](/export-wordpress-data-ai-website-builder-supabase-backend-csv/): keep the keys that hold relationships together.

## Security: handle the hashes responsibly

Migrating hashes is safe, but the migration still moves sensitive account data, so handle it carefully. Never export or store plain-text passwords, WordPress does not keep them anyway, and hashes are the only credential unit you should ever move. Transfer the export over a secure channel, load it straight into Supabase, and delete working copies once loaded rather than leaving a file of user records and hashes lying around. The user data, emails, names, roles, is personal information, so treat the export as confidential and limit who can access it, in line with whatever privacy obligations you operate under. OWASP's [guidance](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html) also recommends upgrading legacy hashes to a strong modern algorithm, which the verify-then-rehash step does automatically. Done this way, the migration ends with stronger password storage than you started with, not weaker, while never exposing a single plaintext credential.

## Common mistakes migrating users

The recurring errors all either disrupt users or break accounts. Forcing a mass password reset, the default lazy path, churns active members for no reason. Trying to import phpass hashes without a custom verifier means none of them validate, so every user is locked out until they reset, the very outcome you were avoiding. Exporting only emails and hashes, dropping the user IDs, leaves logins working but order history and content orphaned. Exporting or logging plain-text passwords is a serious security mistake (and unnecessary, since WordPress does not store them). And leaving the export file unsecured exposes personal data and hashes. Each is avoided by migrating hashes with a verify-then-rehash step, preserving IDs and account fields, and handling the export securely, which is what makes the move both seamless for users and safe.

## Key points to remember

Move WordPress users to Supabase by migrating their phpass password hashes, never plain text, and verifying the old hash on first login, then rehashing to Supabase's format, so members keep logging in with their existing passwords and no one has to reset. Add a custom first-login verifier to bridge phpass to Supabase's scheme, and preserve emails, roles, and especially user IDs so order history and authored content stay attached to the right accounts. Handle the export as sensitive data over a secure channel and delete working copies, and the verify-then-rehash step leaves you with stronger password storage than before. WPBuildAI exports the user table to a Supabase-ready format with hashes intact, so authentication moves without locking anyone out; send your site URL for a fixed quote.

Not affiliated with Supabase, WordPress, or Lovable.