2

I have two wordpress website Ex:abc.com and xyz.abc.com (both are in wordpress).

i want to implement single sign on(SSO) into this two website without using multisite functionality.

3
  • This plugin may be suitable for what you want. wordpress.org/plugins/wp-multisite-sso Commented Jul 3, 2017 at 10:42
  • Thank you for reponse This plugin use multisite concept but my requirement is different i want implement single sing on without multisite concept if i use multisite then my site url will change that i dont want Ex:abc.com (Main Site) other wordpress site xyz.abc.com Commented Jul 3, 2017 at 11:46
  • If you want to keep the websites completely separated, you can with WP Remote Users Sync (disclaimer: I am the author of the plugin).
    – froger.me
    Commented Mar 16, 2020 at 10:36

1 Answer 1

8

Let's assume that we have two websites, mentioned in your question - abc.com, xyz.abc.com, and their table prefixes are - ab_, xy_.

Requirements

Both websites must be installed within the same domain. Both websites must share the same database using different table prefixes. Both websites must share user tables ( ex. ab_users, ab_usermeta ).

Websites' wp-config.php files

The wp-config.php files of both websites should be identical, with one exception, $table_prefix for abc.com website should be ab_, and for xyz.abc.com should be xy_. See wp-config.php for abc.com, below:

<?php
/**
 * The base configurations of the WordPress.
 *
 * This file has the following configurations: MySQL settings, Table Prefix,
 * Secret Keys, WordPress Language, and ABSPATH. You can find more information
 * by visiting {@link http://codex.wordpress.org/Editing_wp-config.php Editing
 * wp-config.php} Codex page. You can get the MySQL settings from your web host.
 *
 * This file is used by the wp-config.php creation script during the
 * installation. You don't have to use the web site, you can just copy this file
 * to "wp-config.php" and fill in the values.
 *
 * @package WordPress
 */

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'abc'); // change it, to match your installation  

/** MySQL database username */
define('DB_USER', 'abcadmin'); // change it, to match your installation

/** MySQL database password */
define('DB_PASSWORD', 'database pasword here'); // change it, to match your installation

/** MySQL hostname */
define('DB_HOST', 'localhost'); // change it, to match your installation

/** Database Charset to use in creating database tables. */
define('DB_CHARSET', 'utf8');

/** The Database Collate type. Don't change this if in doubt. */
define('DB_COLLATE', '');

/**#@+
 * 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',              'use generated value here');
define('SECURE_AUTH_KEY',       'use generated value here');
define('LOGGED_IN_KEY',         'use generated value here');
define('NONCE_KEY',             'use generated value here');

define('AUTH_SALT',             'use generated value here');
define('SECURE_AUTH_SALT',      'use generated value here');
define('LOGGED_IN_SALT',        'use generated value here');
define('NONCE_SALT',            'use generated value here');

define('COOKIE_DOMAIN',         '.abc.com');
define('COOKIEPATH',            '/');
define('COOKIEHASH',            md5('abc.com'));

/**#@-*/

/**
 * WordPress Database Table prefix.
 *
 * You can have multiple installations in one database if you give each a unique
 * prefix. Only numbers, letters, and underscores please!
 */
$table_prefix  = 'ab_'; // in wp-config.php for xyz.abc.com change it to 'xy_'

/* uncomment these two lines after successful website installation */
// define('CUSTOM_USER_TABLE', 'ab_users');
// define('CUSTOM_USER_META_TABLE', 'ab_usermeta');

/**
 * For developers: WordPress debugging mode.
 *
 * Change this to true to enable the display of notices during development.
 * It is strongly recommended that plugin and theme developers use WP_DEBUG
 * in their development environments.
 */
define('WP_DEBUG', false);

/* That's all, stop editing! Happy blogging. */

/** Absolute path to the WordPress directory. */
if ( !defined('ABSPATH') )
    define('ABSPATH', dirname(__FILE__) . '/');

/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');

New installations

Create an empty database to be used by both installations.

Drop wp-config.php for abc.com to the root of abc.com and do the installation. Do not login to your website, yet. Write down administrator's user name and password.

Drop wp-config.php for xyz.abc.com to the root of xyz.abc.com and do the installation. Do not login to your new website.

In both websites, create mu-plugins folder in /wp-content, if it does not exist.

Make fpw-sync-users.php file with the following content:

<?php
/*
  Plugin Name: FPW Synchronize Shared Users
  Author: Frank P. Walentynowicz
  Author URI: https://fw2s.com
  Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
 */

// Users synchronization on admin login
function fpw_synchronize_admins_on_admin_login( $user_login, $user ) {
    if ( array_key_exists( 'administrator', $user->caps ) ) {
        global $wpdb;
        $site_prefix = $wpdb->prefix;
        $admins_only = true;

        $other_prefixes = array(
            'xy_',
        );

        $args = array( 
            'fields'    => 'ID',
        );
        if ( $admins_only )
            $args[ 'role' ] = 'administrator';

        $users = get_users( $args );

        foreach ( $users as $id ) {
            $cap = get_user_meta( $id, $site_prefix . 'capabilities', true );

            foreach ( $other_prefixes as $prefix )
                update_user_meta( $id, $prefix . 'capabilities', $cap );
        }
    }
}
add_action( 'wp_login', 'fpw_synchronize_admins_on_admin_login', 10, 2 );

// User synchronization on admin create user
function fpw_synchronize_user_on_admin_register( $id ) {
    $me = wp_get_current_user();
    if ( array_key_exists( 'administrator', $me->caps ) ) {
        $other_prefixes = array(
            'xy_',
        );
        $user = get_user_by( 'id', $id );
        $cap = $user->caps;
        foreach ( $other_prefixes as $prefix )
            update_user_meta( $id, $prefix . 'capabilities', $cap );
    }
}
add_action( 'user_register', 'fpw_synchronize_user_on_admin_register', 10, 1 );

// User synchronization on profile update
function fpw_synchronize_user_on_profile_update( $user_id ) {
    if ( current_user_can( 'edit_user', $user_id ) ) {
        $other_prefixes = array(
            'xy_',
        );
        $cap = array( $_POST[ 'role' ] => true, );
        foreach ( $other_prefixes as $prefix )
            update_user_meta( $user_id, $prefix . 'capabilities', $cap );
    }
 }
add_action('edit_user_profile_update', 'fpw_synchronize_user_on_profile_update');

Drop fpw-sync-users.php file to /wp-content/mu-plugins folder of both websites.

Modify fpw-sync-users.php file for xyz.abc.com, by replacing every occurence of:

$other_prefixes = array(
    'xy_',
);

with:

$other_prefixes = array(
    'ab_',
);

Modify wp-config.php files for both websites, by uncommenting these two defines:

// define('CUSTOM_USER_TABLE', 'ab_users');
// define('CUSTOM_USER_META_TABLE', 'ab_usermeta');

All done. Login to abc.com and go to xyz.abc.com. You will be logged in to this website, as well.

You can drop xy_users and xy_usermeta tables from the database, because they will not be used, anymore.

Existing installations

Things are getting slightly more complicated, when we deal with already existing websites, with separate databases.

Important: make a backup of wp-config.php files, and databases, of both websites, before proceeding!

Let's use the database of abc.com website as a shared database. We have to export all tables ( except users and usermeta ) from xyz.abc.com database, and import them into abc.com database.

Make sure that table prefix for xyz.abc.com database is different from table prefix for abc.com database. If it is different, you can skip the following procedure of changing table prefix for xyz.abc.com.

Change table prefix for xyz.abc.com: install and activate WP Prefix Changer plugin. Run its procedure to change the prefix. Deactivate and delete this plugin. Now you are ready for export / import tables.

Export tables from xyz.abc.com database, and import them into abc.com database. For this, you can use phpMyAdmin, or any other tool available.

Modify wp-config.php ( see wp-config.php example from New installations section ) for abc.com, by adding the following defines:

define('COOKIE_DOMAIN',         '.abc.com');
define('COOKIEPATH',            '/');
define('COOKIEHASH',            md5('abc.com'));

and

define('CUSTOM_USER_TABLE', 'ab_users');
define('CUSTOM_USER_META_TABLE', 'ab_usermeta');

Modify wp-config.php for xyz.abc.com, by replacing database related defines, to match your shared database values. Add defines, you just added to wp-config.php of abc.com. Replace keys and hashes defines, to match these defines in wp-config.php for abc.com.

Add ( as described in New installations section ) fpw-sync-users.php synchronization plugin to /wp-content/mu-plugins folders of both websites, and modify its prefixes accordingly.

That's it. Now you have shared users, who can use SSO.

10
  • Thank you for your kind response I have implemented your code i am able to login with single table in both website but when i login in abc.com it wont login in xyz.abc.com Commented Jul 4, 2017 at 9:47
  • I am implementing your code in localhost will that will be work in localhost, if yes then what should i specify in COOKIE_DOMAIN field path of my file like "localhost/test/abc.com"???? Commented Jul 4, 2017 at 12:19
  • To be honest, I've never used it on 'localhost'. I don't know. You might try '.localhost' ( note the dot in front of main domain ), but I cannot guarantee it. Even my dev environments are on standard domains. I've implementations on several production sites. Commented Jul 4, 2017 at 15:03
  • some how i manage to create virtual host and as you mention COOKIE_DOMAIN i have implemented that with abc.com and xyz.abc.com but i am facing problem in that once i login in abc.com it wont automatically login in xyz.abc.com and if i login in xyz.abc.com mannually automatically logged out in abc.com Commented Jul 4, 2017 at 18:01
  • Did you try define('COOKIE_DOMAIN','.abc.com');? Did you make aliases in local hosts? I'm trying to install XAMPP on my Windows 10 for testing. I'll try to test it there. I need some time as I'm busy now. Commented Jul 4, 2017 at 20:03

Not the answer you're looking for? Browse other questions tagged or ask your own question.