Lafayette Community Church uses a couple different WordPress installations for its website.
- The first WordPress installation is the main website, and it is located at http://lafayettecc.org/news/.
- The second WordPress installation is for blogs and devotionals, and it is located at http://lafayettecc.org/blogs/.
I set it up so that users need log in only once, and their login persists across both sites. I didn’t need to use any plugins or LDAP or third party authentication systems for this.
Here’s what you need to do to make it work for your site as well:
- Both WordPress installations must be running on the same domain, even though they might reside in different subdirectories or different subdomains.
- Both installations must be running on the same database but with different table prefixes.
- If your secondary site already has users, you will need to do manual database updates, and that’s beyond the scope of this tutorial. The rest of this tutorial assumes you are okay with the fact that your secondary installation’s user table will be completely ignored and both installations will use the primary installation’s user table.
- Change the
wp-config.php
file on the secondary blog to tell WordPress which table to use for users.
define('CUSTOM_USER_TABLE', 'blog1_users'); // replace blog1 with the table prefix from your
define('CUSTOM_USER_META_TABLE', 'blog1_usermeta'); // main wordpress installation
- Change both
wp-config.php
files to unify the cookies across the two installations. I’ll go into more detail here.
Unifying Authentication Cookies across multiple WordPress Installations
WordPress uses two cookies to handle authentication, but there are a number of settings that need to be synchronized between installations so that WordPress can read and understand the cookies properly.
Authentication Keys
Your WordPress installations may or may not have custom authentication keys set up, but in order for this to work properly, you should have the same keys set up on each installation. In wp-config.php
on BOTH sites, add these lines:
/**#@+
* Authentication Unique Keys and Salts.
*
* Change these to different unique phrases!
* You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
* You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
*
* @since 2.6.0
*/
define('AUTH_KEY', 'custom-hash-here');
define('SECURE_AUTH_KEY', 'custom-hash-here');
define('LOGGED_IN_KEY', 'custom-hash-here');
define('NONCE_KEY', 'custom-hash-here');
define('AUTH_SALT', 'custom-hash-here');
define('SECURE_AUTH_SALT', 'custom-hash-here');
define('LOGGED_IN_SALT', 'custom-hash-here');
define('NONCE_SALT', 'custom-hash-here');
Of course, you want to replace “custom-hash-here” with different random strings, and of course, if you already have these values set in your wp-config.php
files, you need to replace what’s currently there with these so that both sites are using the same exact settings.
Cookie Settings
Hash, Domain, and Path
When WordPress uses three defined constants when creating authentication cookies for the browser: COOKIEHASH
, COOKIE_DOMAIN
, and COOKIEPATH
.
define('COOKIEHASH', 'custom-hash-here'); //define the hash
define('COOKIE_DOMAIN', '.example.org'); //remove the leading dot if you aren't using subdomains
define('COOKIEPATH', '/'); //this must be a parent directory to all WP installations
Again, these three settings must be exactly the same across your all installations, but there are additional concerns:
The COOKIE_DOMAIN
and the COOKIEPATH
must be parents of both installations. That means, if your installations are on separate subdomains, the COOKIE_DOMAIN
must apply to both (a leading dot before the domain name will accomplish this), and if your installations are using separate subdirectories, your COOKIEPATH
must be a parent to both. To be safe, you can make it ‘/’, but you actually want your cookies to be as specific as possible, so if one blog is in example.org/wordpress/blog1
and the other blog is in example.org/wordpress/blog2
, you can use /wordpress
as your COOKIEPATH
, or if one blog is blog1.example.org/wordpress
and the other is blog2.example.org/wordpress
, you should also be able to use /wordpress
as your COOKIEPATH
.
Site and Admin
WordPress uses two defined constants to help it look for the right cookies to see if a user has been authenticated. One of those constants is SITECOOKIEPATH
and it is used by the WordPress frontend. The other is ADMIN_COOKIE_PATH
and it is used by the WordPress backend.
Simply set both of them to be the same as the COOKIEPATH
and you should be fine.
define('SITECOOKIEPATH', COOKIEPATH);
define('ADMIN_COOKIE_PATH', COOKIEPATH);
Conclusion
So, for completeness, here are all the settings together:
In secondary wp-config.php
files:
define('CUSTOM_USER_TABLE', 'blog1_users'); // replace blog1 with the table prefix from your
define('CUSTOM_USER_META_TABLE', 'blog1_usermeta'); // main wordpress installation
In all wp-config.php
files
define('AUTH_KEY', 'custom-hash-here');
define('SECURE_AUTH_KEY', 'custom-hash-here');
define('LOGGED_IN_KEY', 'custom-hash-here');
define('NONCE_KEY', 'custom-hash-here');
define('AUTH_SALT', 'custom-hash-here');
define('SECURE_AUTH_SALT', 'custom-hash-here');
define('LOGGED_IN_SALT', 'custom-hash-here');
define('NONCE_SALT', 'custom-hash-here');
define('COOKIEHASH', 'custom-hash-here');
define('COOKIE_DOMAIN', '.example.org');
define('COOKIEPATH', '/');
define('SITECOOKIEPATH', COOKIEPATH);
define( 'ADMIN_COOKIE_PATH', COOKIEPATH );
Post a comment if it doesn’t work for you.
Kushal
My second website is not able to login and always return back to the wp-login.php. Yes it identifies the cookie being set but doesnt work with perfection
Daniele
Hi Jeff,
Thanks a lot for this tutorial, it helped me a lot.
Why not just switch to a multisite installation?
Jeff Mikels
That’s entirely possible. I did it this way because I didn’t want to go through the effort of transferring an existing site to a multi-site. Perhaps the migration would have been easier than I suspected, and perhaps I will do that in the future, but this was my first solution.
Ray
Nice tutorial Jeff! Very detailed, and yes it works!
One thing though, on the second website, it seems i can’t access the backend. It keeps showing an ‘You do not have sufficient permissions to access this page.’ error. Can you please help me figure it out?
Thanks for the advance response! Cheers!
Mike
Thank you for the tutorial.
Same problem as the above though where on the second site you can’t access the backend as an admin. It’s like it sees the user but doesn’t know it’s an administrator.
Any ideas?
Kuma
That’s because your users from first website don’t have capabilities for second website.
When checking prefix_usermeta table, you can find that your user only has capability for your first website such as wp_capabilities in meta_key column. To allow your user to access second website, you need to add an alternative data with meta_key: ‘prefix_ capabilities’ (prefix for your second site) and meta_value: ‘same value in first site’.
Mayur
Hi,
Good Tutorial! I am facing an issue when user register from
domain.com/site1 then it shows user role to NONE for domain.com/site2. I want to Use same user role like domain.com/site1.
Thanks.
Juanky Aguilera
Thanks! It works!
Bowe
You are a life safer! This took me days to get working, and somehow I always missed a step.. Thanks!
Hamza Ahmed
Hi Jeff, Thanks for the amazing tutorial.
Please recommend me that should I use WordPress multi-site or single instances for managing a large site and will this method automatically signout users when they sign out from one site?
Jeff Mikels
I can’t make a recommendation without knowing your specific requirements. Please feel free to contact me directly if you want a consultation.