Migrating User Authentication from WordPress to Django
John-Michael Oswalt will be covering how he migrated from using WordPress's built-in login system to the user registration and authentication system in Django. This includes User data and hashed passwords, so users did not need to re-register or reset their passwords. Building a user API and updating the PHP app to read from this API using cookies will also be covered.
WordPress Users -> Django Users
You had a small WordPress site with a few users, but now you've grown your user base and the WP authentication system no longer meets your needs.
You've decided to move to Django (or another python framework) and you want to keep all of your users without them being disrupted.
-
Export the data from WordPress
-
Import the data into Django
-
Update staff and superusers
-
Install python requirements, settings
-
Update passwords with Management Command
SELECT id, user_login as username, user_pass as password, display_name as first_name, user_registered as date_joined, "1" as is_active, user_registered as last_login, user_email as email, "0" as is_staff, "0" as is_superuser FROM wp_users
This will give you the default columns you need to the User object in auth. Note that the full name is being added to first_name. You may need to clean that up later.
mysql -u username -p dbname < path/to/export.sql
Above is a brief example of importing in MySQL. You may have a different data backend or preferred GUI tool to do the import. Either way, you need to get the data from step 1 into the new Django database.
UPDATE auth_user SET is_staff = True, is_superuser = True WHERE id in (1, 2, 3, 26, 553)
If you know the IDs of your superusers (Admins in WordPress), then you can simply add them here and run this single query.
An alternative option is to JOIN the wp_usermeta table with wp_users and use wp_user_level to establish staff and superusers.
pip install django-hashers-passlib==0.1
And remember to update your requirements.txt
or similar.
Within your settings.py
file for your django project, add the following:
PASSWORD_HASHERS = (
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
'django.contrib.auth.hashers.BCryptPasswordHasher',
'django.contrib.auth.hashers.SHA1PasswordHasher',
'django.contrib.auth.hashers.MD5PasswordHasher',
'django.contrib.auth.hashers.CryptPasswordHasher',
'hashers_passlib.phpass',
)
The last line will add the phppass
as a valid password hashing option.
from django.contrib.auth.hashers import get_hasher
hasher = get_hasher('phpass')
user.password = hasher.from_orig(user.password)
Then run the command: python manage.py convert_wp_passwords
Old: $P$B8Wa4IPrveTlsVAIPhT5WIot8qfc67/
New: phpass$$P$B8Wa4IPrveTlsVAIPhT5WIot8qfc67/
Django will reformat the password so that it can parse the correct hasher when it attempts to validate a user.
Some people will be able to stop here. Their users are now migrated and can log in and out of the new site just like the old one. However, if you were using the WP backend to support anything else, you will need to create a replacement in Django.
We previously had an XML API to read user data out of WordPress from other apps that we have. We now needed to recreate that in Django.
-
Set an apex domain cookie
-
Create a View to display user info
-
Return XML
-
Read XML from other apps
SESSION_COOKIE_DOMAIN = ".example.com"
Note the leading '.' on the domain name.
You may also want a custom cookie name, which can be set with:
SESSION_COOKIE_NAME = "mysite_sessionid"
We will need to accept the cookie value as an input in order to send back the correct user info.
See views.py and urls.py
<?xml version="1.0" encoding="UTF-8"?>
<user status="{{ requested_user.status }}" username="{{ requested_user.username }}" email="{{ requested_user.email }}" />
The methods to do this will vary from language to language, and if we need any additional info about the user, we can add it to our XML.