web-dev-qa-db-fra.com

Cookie de connexion sur plusieurs domaines du réseau avec mappage

J'ai un sous-répertoire réseau Wordpress avec plus de 50 sites, il se trouve sur un domaine principal de wordpress.example.com.

Un client, johndoe , au sein de mon réseau aura (intentionnellement) un back-end incluant le site principal (pour des raisons de personnalisation et de marque):

wordpress.example.com/johndoe/wp-admin/

puis par mappage de domaine avec WordPress MU Mappage de domaine par Donncha O Caoimh , un front-end de:

johndoe.com/


Mon problème est que le cookie de connexion associe uniquement à wordpress.example.com et qu'il n'a aucun lien avec johndoe.com, de sorte que le serveur frontal ne reconnaît pas qu'un utilisateur est réellement connecté. Cela donne:

  • pas de barre d'outils utilisateur sur le front-end
  • un bouton de messages "APERÇU des modifications" ne fonctionne pas
  • is_user_logged_in() ne fonctionne pas en frontal
  • les plugins de constructeur de pages front-end ne fonctionneront pas

En désactivant le "login à distance", je sais que je peux créer le back-end du site johndoe.com/wp-admin/ qui résoudrait tous les problèmes susmentionnés. Cependant, garder le domaine principal pour le back-end est crucial. Dans toutes mes lectures, je n'ai pas trouvé de solution et je laisse cette question reposer pendant des années.

Je sais que Wordpress.com (lui-même alimenté par un réseau Wordpress) semble avoir résolu ce problème. Lorsque je suis connecté à wordpress.com, je me rends sur un blog Wordpress.com aléatoire tel que https://longitudes.ups.com je peux voir mon identifiant .com, et la barre d’outils ne semble pas être un iframe ou quelque chose de stupide fait.

Ma question est donc la suivante: si le domaine frontal d’un site Wordpress est différent du serveur principal, est-il possible de lier le cookie de connexion aux deux? Si la réponse est "vous ne pouvez pas" (comme toutes mes recherches sont de retour), mon suivi est, bien comment les gens d'Automattic le font-ils?

1
David Sword

WordPress décide si vous êtes connecté ou non en vérifiant AUTH_COOKIE et LOGGED_IN_COOKIE. Comme vous avez pu le constater, ces cookies sont installés dans le même domaine que celui de votre site, A. Ajouter les mêmes cookies à votre deuxième domaine B obligerait votre utilisateur à se connecter à deux domaines A et B. Bien sûr, définir un cookie à partir du domaine A pour le second domaine B constituerait une faille importante en matière de sécurité. Vous devez donc envoyer les valeurs de cookie du domaine A au domaine B et définir ces cookies dans le domaine B.

Donc, voici ce que nous devons faire:

  • lire les cookies AUTH_COOKIE et LOGGED_IN_COOKIE sur le domaine A
  • envoyer des cookies AUTH_COOKIE et LOGGED_IN_COOKIE du domaine A au domaine B
  • définir les cookies AUTH_COOKIE et LOGGED_IN_COOKIE sur le domaine B

Pour lire les cookies, nous devons utiliser deux filtes set_auth_cookie et set_logged_in_cookie. Pour définir les cookies sur le domaine B, le navigateur des utilisateurs doit être sur le site B. Nous devons donc rediriger l'utilisateur du domaine A vers le domaine B avec des valeurs de cookie. La redirection avec GET params n’est pas une option, les cookies sont sensibles à la sécurité, nous devons utiliser la demande POST. Pour rediriger les utilisateurs et envoyer les cookies avec POST, nous pouvons créer un formulaire HTML simple avec l'URL pointée sur le domaine B. Une fois l’utilisateur redirigé, nous pouvons définir des cookies sur le domaine B et le redonner à un domaine A.

J'ai créé un code de travail pour mon implémentation.

/**
 * DOMAIN A PART PLUGIN
 */

class WPSE_287556_Send_Cookies {

    /**
     * Domain which user have to be redirected
     *
     * @var array
     */
    private $domainB = 'example.com';

    /**
     * Array of cookies to send
     *
     * @var array
     */
    private $cookies = array();

    /**
     * WPSE_287556_Send_Cookies constructor.
     */
    public function __construct()
    {
        /**
         * Define plugin related hooks
         */
        $this->define_hooks();
    }

    /**
     * Save auth and logged in cookies to array
     */
    public function save_cookie( $cookie, $expire, $expiration, $user_id, $scheme, $token ) {

        $this->cookies[] = $data = array(
            'cookie' => $cookie,
            'expire' => $expire,
            'scheme' => $scheme,
        );
    }

    /**
     * Display redirect post form
     *
     * We should not redirect user with cookies in get parameters because this is
     * no safe. We also can not redirect user with post parameters. We can create
     * html post form and submit it with js.
     */
    public function display_redirect_form( $redirect_to, $requested_redirect_to, $user ) {

        if( is_array( $this->cookies ) && !empty( $this->cookies ) ):

            $url = ( is_ssl() ) ? 'https://' : 'http://' . $this->domainB . '/';
            ?>

            <form action="<?php echo esc_url( $url ); ?>" method="post" style="display: none;" id="post_redirect_form">

                <input type="hidden" name="action" value="set_cookies" >

                <?php foreach($this->cookies as $index => $cookie): ?>
                    <input type="hidden" name="cookies[<?php esc_attr_e( $index ); ?>][cookie]" value="<?php esc_attr_e( $cookie['cookie'] ); ?>" >
                    <input type="hidden" name="cookies[<?php esc_attr_e( $index ); ?>][expire]" value="<?php esc_attr_e( $cookie['expire'] ); ?>" >
                    <input type="hidden" name="cookies[<?php esc_attr_e( $index ); ?>][scheme]" value="<?php esc_attr_e( $cookie['scheme'] ); ?>" >
                <?php endforeach; ?>

                <input type="hidden" name="redirect_to" value="<?php esc_attr_e( $redirect_to ); ?>" >
            </form>
            <script> document.getElementById('post_redirect_form').submit(); </script>

            <?php exit; ?>

        <?php endif;

        return $redirect_to;
    }

    /**
     * Define plugin related hooks
     */
    private function define_hooks() {

        /**
         * Save cookies hook
         */
        add_action( 'set_auth_cookie', array($this, 'save_cookie'), 10, 6 );
        add_action( 'set_logged_in_cookie', array($this, 'save_cookie'), 10, 6 );

        /**
         * Display redirect post form
         *
         * This filter is used to modify redirect url after login. There is no
         * better place to modify page content after user login. Additionally
         * we have access to $redirect_to url which we can use later.
         */
        add_filter('login_redirect', array( $this, 'display_redirect_form' ), 10, 3);
    }
}

new WPSE_287556_Send_Cookies();

/**
 * END OF DOMAIN A PART PLUGIN
 */

/**
 * DOMAIN B PART PLUGIN
 */

class WPSE_287556_Set_Cookies {

    /**
     * WPSE_287556_Set_Cookies constructor.
     */
    public function __construct()
    {
        /**
         * Define plugin related hooks
         */
        $this->define_hooks();
    }

    /**
     * Set auth and logged in cookies
     */
    public function set_cookies() {

        // Check if request is "set auth cookie" request
        if( $_SERVER['REQUEST_METHOD'] === 'POST' && isset( $_POST['action'] ) && $_POST['action'] === 'set_cookies' ) {

            $args = array(
                'redirect_to'   => FILTER_SANITIZE_URL,
                'cookies'    => array(
                    'filter' => FILTER_SANITIZE_STRING,
                    'flags'  => FILTER_REQUIRE_ARRAY,
                ),
            );

            // Read and filter all post params
            $post = filter_input_array(INPUT_POST, $args);

            $redirect_to = $post['redirect_to'];
            $cookies     = $post['cookies'];

            foreach( $cookies as $cookie_params ){

                $scheme = $cookie_params['scheme'];
                $cookie = $cookie_params['cookie'];
                $expire = (int) $cookie_params['expire'];

                // Decide which cookie to set
                switch( $scheme ) {

                    case 'logged_in':

                        // Set logged in cookie, most of the code is from wp_set_auth_cookie function
                        setcookie( LOGGED_IN_COOKIE, $cookie, $expire, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true);

                        if ( COOKIEPATH != SITECOOKIEPATH )
                            setcookie(LOGGED_IN_COOKIE, $cookie, $expire, SITECOOKIEPATH, COOKIE_DOMAIN, is_ssl(), true);

                        break;

                    case 'secure_auth':
                    case 'auth':

                        // Set auth cookie, most of the code is from wp_set_auth_cookie function
                        if ( $scheme === 'secure_auth' ) {
                            $auth_cookie_name = SECURE_AUTH_COOKIE;
                        } else {
                            $auth_cookie_name = AUTH_COOKIE;
                        }

                        setcookie($auth_cookie_name, $cookie, $expire, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN, is_ssl(), true);
                        setcookie($auth_cookie_name, $cookie, $expire, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, is_ssl(), true);

                        break;
                }
            }

            // Redirect user to previous site
            header( 'Location: ' . esc_url( $redirect_to ) );
            exit;
        }
    }

    /**
     * Define plugin related hooks
     */
    private function define_hooks() {

        /**
         * Set cookies from request
         */
        add_action( 'init', array($this, 'set_cookies'));
    }
}

new WPSE_287556_Set_Cookies();

/**
 * END OF DOMAIN B PART PLUGIN
 */
1
kierzniak

Pourriez-vous vérifier ces définitions dans votre fichier wp-config.php?

define('ADMIN_COOKIE_PATH', '/');
define('COOKIE_DOMAIN', '');
define('COOKIEPATH', '');
define('SITECOOKIEPATH', ''); 

Et aussi s'il vous plaît vérifier vos définitions multisites.

define('WP_ALLOW_MULTISITE', true);
define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', false);
define('DOMAIN_CURRENT_SITE', 'your-domain.com');
define('PATH_CURRENT_SITE', '/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);
define('SUNRISE', 'on');
0
Serkan Algur