webleads-tracker

WordPress & Référencement naturel
Mes servicesWordPress - Référencement
Hébergement WordPress
Vous êtes ici : SeoMix » WordPress » Hacks, fonctions et snippets WordPress » Déplacer l’administration de WordPress

Déplacer l’administration de WordPress

J’ai effectué une mission de quelques moi au sein d’un grand groupe de presse. Au sein de l'équipe, je me suis occupé de migrer l'ancien backoffice "Web" vers le nouveau : WordPress.

L'architecture technique de ce site est en composée de trois serveurs frontaux (devant s'occuper de l'affichage du site) et d'un serveur de base de données. En réalité, seuls deux des serveurs frontaux sont utilisés pour afficher le site, le troisième ayant été délaissé suite à une incompatibilité de l'application de réplication du cache.

Ainsi, à la fin de cette migration, les deux serveurs frontaux ont dû répondre à la fois au frontoffice du site, mais également au backoffice. Le fait d'avoir un troisième serveur, inexploité, a fait surgir une idée: déplacer cette charge du backoffice sur ce serveur. Les deux serveurs frontaux porteraient alors bien leur nom et l'autre aurait une réelle utilité.

Le principe

Sur le papier, cela reste cohérent et l'architecture n'est pas si complexe puisque les personnes se connectant sur le backoffice travaillent au sein des locaux de mon client: on n'ouvre pas le serveur vers l'extérieur, mais on redirige un sous-domaine (du style "admin.mondomaine.fr") vers ce serveur.

Il est même simple de régler certains détails comme le cache, puisqu'on peut toujours demander à ce serveur "back" de se connecter sur un des caches "front".

Reste alors un problème : WordPress ne connaît qu'une URL pour son admin. C'est www. mondomaine.fr.fr/wp-admin et pas autre chose. Comme vous le savez, WordPress stocke les URL en dur dans la base, et certaines fonctions du coeur ont même la chaîne 'wp-admin' codée en dur ! Cela implique que WordPress redirige quiconque essaie d'accéder à son administration vers cette URL.

A première vue, c'est donc pratiquement mission impossible de déplacer l'administration sur un sous-domaine, surtout si on ne veut pas toucher au cœur...

Challenge accepted!

Le VHost

Je ne vais pas expliquer ici ce qu'est un VHost, mais pour ceux que ça intéresse, Wikipédia propose une définition claire et concise.

Une méthode de développement possible avec WordPress est d'installer un serveur HTTP local puis de créer un VHost afin de rediriger l'URL du site de production vers la version locale. Cela permet de ne pas s'embrouiller avec les URLs enregistrées dans la base : ce sont les mêmes.

Chez ce client, c'est un peu différent puisqu'il y a plusieurs environnements à gérer. Cela n'empêche pas la méthode des VHosts en local, puisque cela a l'avantage de permettre une configuration quasi-identique (les URLs se ressemblent, on peut définir des variables d'environnement pour le VHost, l'installation multisite de WordPress accepte le mode "sous-domaines", ...).

Ainsi, voici un exemple de VHost pointant vers la partie administration d'une installation de WordPress.

<VirtualHost *:80>
        ServerName admin.mondomaine.fr
        ServerAdmin monmail@monmail.com
        DocumentRoot "C:/wamp/www/mondomaine.fr/wp-admin/"
        ErrorLog "logs/mondomaine.error.log"
        CustomLog "logs/mondomaine.access.log" common
        <Directory "C:/wamp/www/mondomaine.fr/wp-admin/">
            Options FollowSymLinks
            AllowOverride All
            Order deny,allow
            Deny from all
            Allow from all
    </Directory>
</VirtualHost>

Wp-login.php

Le fonctionnement de WordPress pour la phase de connexion est simple : on redirige l'utilisateur vers l'URL "<site_url>/wp-login.php", où <site_url> est l'adresse du front. Cela nous pose problème puisqu'on veut également que cette phase de connexion soit prise en charge par notre administration.

Ceci nous impose donc de copier le fichier wp-login.php vers le dossier wp-admin/ où est située toute l'administration. Étant donné que c'est un fichier qui se rajoute, il a peu de chances de se faire écraser par une mise à jour de WordPress et c'est tant mieux.

Une fois ce fichier copié, il va falloir un petit peu le modifier. D'une part parce que le bootstrap n'est plus à jour au niveau de l'arborescence, et puis parce que les formulaires pointent toujours vers l'ancien fichier.

Du coup, on va effectuer les modifications suivantes :

  • ligne 12 :
require( dirname(__FILE__) . '/../wp-load.php' );
  • lignes 404, 451, 510 et 630 :

action="<?php echo esc_url( admin_url( 'wp-login.php', 'login_post' ) ); ?>"

On a ainsi un fichier wp-admin/wp-login.php qui charge correctement le cœur de WordPress et qui se rappelle lui-même lors d'un appel de formulaire... Enfin presque.

Effectivement, la fonction admin_url() retourne toujours "mondomaine.fr/wp-admin/", ce n'est pas vraiment ce qui est voulu. Et puis de toute façon, WordPress ne connaissant pas cette URL, il ne veut pas afficher notre belle page.

Encore un petit effort.

La configuration

A partir de cette étape, on va mettre en place la configuration nécessaire pour faire croire à WordPress que l'URL de son administration est bien notre sous-domaine.

Tout va se passer dans le fichier wp-config.php. Tout d'abord, il va falloir définir une nouvelle constante afin de stocker cette URL. Appelons-la par exemple 'ADMIN_SITEURL' :

define('ADMIN_SITEURL', 'http://admin.mondomaine.fr');

Ensuite, afin que la connexion se passe bien et que WordPress puisse retrouver les données grâce à ses cookies, il faut surcharger 2 constantes définies normalement par le coeur. La première définit le chemin d'accès à l'administration (sans le domaine), donc par défaut '/wp-admin'. La deuxième définit le domaine sur lequel s'appliquent les cookies, soit "mondomaine.fr" par défaut.

define( 'ADMIN_COOKIE_PATH', FALSE );
define( 'COOKIE_DOMAIN', '.mondomaine.fr' );

Ici, on définit donc que les cookies sont partagés entre tous les sous-domaines de "mondomaine.fr" et que le cookie de l'admin sera disponible depuis la racine.

Enfin, toujours dans le fichier wp-config.php, afin d'éviter une petite erreur PHP qui survient après avoir fait tout ça dans le fichier wp-includes/vars.php (à la ligne 28), il convient d'ajouter le bout de code suivant :

if('http://' . $_SERVER['HTTP_HOST'] == ADMIN_SITEURL)
    $_SERVER['PHP_SELF'] = '/wp-admin' . $_SERVER['PHP_SELF'];

Le fait de corriger l'erreur permet également de bien définir la variable $pagenow, variable globale disponible partout dans l'administration, et sur laquelle se basent quelques contrôles et/ou fonctionnalités.

Les filtres

Nous voyons le bout du tunnel désormais ! Toute la préparation a été faite et même les cookies sont bien cuits, il ne nous reste plus qu'à modifier les valeurs que récupère WordPress grâce à quelques fonctions et quelques filtres. Ces filtres pourront être placés dans le thème (le fichier functions.php par exemple), ou dans un plugin dédié.

Première valeur : l'URL de l'administration, bien sûr ! La fonction admin_url() est là pour ça, et elle contient un filtre : "admin_url".

function mondomaine_admin_url($admin_url, $path) {
        // Admin-ajax must be accessed from the front (otherwise the AJAX calls won't work because of cross-domain securities)
        // so don't overwrite this URL in case we found 'admin-ajax.php' in the needed URL
        if(is_admin()|| 0 !== strpos($path, 'admin-ajax.php')){
            $admin_url = ADMIN_SITEURL.'/';

            if ( !empty($path) && is_string($path) && strpos($path, '..') === false )
                $admin_url .= ltrim($path, '/');
        }

        return $admin_url;
    }

    add_filter('admin_url', 'mondomaine_admin_url', 10, 2);

On reprend ici le fonctionnement de la véritable fonction admin_url() du coeur, sauf que l'on prend comme URL de base notre sous-domaine.

Petite formalité en plus : on vérifie si l'URL demandée n'est pas celle du fichier "admin-ajax.php". En effet, ce fichier sert d'agrégateur pour tous les appels AJAX faits au sein de WordPress, que ce soit depuis l'administration ou depuis le frontoffice. Ce qui veut dire que si l'on a installé un plugin qui effectue des appels AJAX depuis le frontoffice, il ira taper sur cette URL.

On pourrait le laisser avec le sous-domaine, sauf que pour des raisons de sécurité, il est interdit de faire des appels AJAX entre deux domaines différents : l'appel va donc échouer... Il serait possible de mettre en place des autorisations spécifiques pour laisser passer ces appels, mais ce n'est pas le but de notre solution ici : on laisse donc ce fichier accessible depuis le front à l'adresse habituelle (mondomaine.fr/wp-admin/admin-ajax.php).

Deuxième valeur : l'URL de la page de connexion. Sur le même modèle que la fonction admin_url()login_url() peut être filtrée.

function mondomaine_login_url($login_url_wp, $redirect) {
        $login_url = admin_url('wp-login.php', 'login');

        if ( !empty($redirect) )
            $login_url = add_query_arg('redirect_to', urlencode($redirect), $login_url);

        if ( FALSE !== strpos($login_url_wp, 'reauth') )
            $login_url = add_query_arg('reauth', '1', $login_url);

        return $login_url;
    }

    add_filter('login_url', 'mondomaine_login_url', 10, 2);

Toujours de la même manière, on reprend le fonctionnement de la fonction du coeur de WordPress, mais en indiquant que notre fichier "wp-login.php" se trouve dans l'administration.

Troisième valeur : l'URL de déconnexion. On commence à être habitués : il existe un filtre "logout_url".

function mondomaine_logout_url($logout_url_wp, $redirect) {
        $args = array( 'action' => 'logout' );
        if ( !empty($redirect) ) {
            $args['redirect_to'] = urlencode( $redirect );
        }

        $logout_url = add_query_arg($args, admin_url('wp-login.php', 'login'));
        $logout_url = wp_nonce_url( $logout_url, 'log-out' );

        return $logout_url;
    }

    add_filter('logout_url', 'mondomaine_logout_url', 10, 2);

Encore une fois, on ne change que l'URL du fichier "wp-login.php" par rapport à la fonction du coeur.

La délivrance

Ca y est ?! Et bien oui. L'administration est accessible depuis l'URL "admin.mondomaine.fr", on peut s'y connecter, y naviguer et tout ça sans avoir perdu les fonctionnalités de base de WordPress.

Pourtant, je ne suis pas sûr à 100% que tous les cas de figure soient pris en compte ici. Je n'ai eu besoin que de ces filtres, mais peut-être y en a-t-il d'autres à ajouter pour compléter la configuration. De plus, si certains plugins que vous avez installés n'utilisent pas les fonctions dédiées comme admin_url(), il y aura sûrement quelques effets de bord...

Dernier point, et pas des moindres : Internet Explorer. Lors de la mise en place de mon POC (Proof Of Concept), j'ai été confronté à un bug assez perturbant concernant IE. Lorsque l'on se connectait à l'administration, puis qu'on voulait afficher le frontoffice du site, la page plantait au premier appel de "document.write('</style>');", et seulement cet appel (les autres "document.write" passaient).

Après plusieurs recherches du côté des cookies ou de l'objet javascript document géré par IE, je suis arrivé à déterminer qu'une portion de code pouvait être retirée pour que ce bug n'apparaisse plus. Cette portion de code est un ajout de style fait par WordPress directement dans le <head> de la page, nécessaire pour ne pas imprimer la barre d'administration avec le reste de la page :

<style type="text/css" media="print">#wpadminbar { display:none; }</style>

Ce code est ajouté par la fonction wp_admin_bar_header(), appelée lors d'une action WordPress : "wp_head". Il suffisait donc de supprimer l'appel de cette fonction sur ce hook pour ne plus avoir le bug.

function mondomaine_remove_admin_bar_header() {
        remove_action('wp_head', 'wp_admin_bar_header');
    }

    add_action('init', 'mondomaine_remove_admin_bar_header', 11);

Afin de ne pas perdre la fonctionnalité qui consiste à cacher la barre d'admin lors d'une impression, il convient tout de même de remettre ce style quelque part, par exemple au sein d'une feuille de style dédiée au print déjà incluse sur le site.

Pour aller plus loin

Je suis preneur de commentaires ou retours d'expérience sur ce système de déplacement de l'administration : est-ce que vous trouvez cela utile ? Allez-vous vous servir de cette astuce ? Avez-vous déjà essayé mais abandonné puisqu'aucune documentation n'existe ? Avez-vous des remarques, des questions sur la mise en place ? Bref, qu'en pensez-vous ?

Twitter de l'agence : @GLOBALISms

Le site de l'agence : WP Chrono.

Les thèmes relatifs

Voici les thématiques abordées par Déplacer l’administration de WordPress:

14 commentaires
  1. Stéphane
    3 messages

    Stéphane - Le 31 mai 2012, 08:24

    Wahh eh beh ! Je n’avais jamais pensé à déplacer l’administration du site et à première vue je n’aurai pas cru que ce serait spécialement difficile.
    Sauf que, comme tu dis, « monsite.com/wp-admin » est la seule page reconnue par wordpress donc…
    En tout cas merci pour toutes ces explications, c’était très agréable à lire et si je souhaite déplacer mon admin un jour, je saurai vers quel site me tourner :p

  2. Yoann
    4 messages

    Yoann - Le 31 mai 2012, 09:23

    Oui vraiment, c’est un bel article qui devrait me servir dans quelques semaines.
    D’un point de vue sécurité c’est un véritable plus.
    Les développeurs de wordpress devraient prévoir cette possibilité dans une future version !

  3. Willy Bahuaud
    31 messages

    Willy Bahuaud - Le 31 mai 2012, 09:28

    Waw !! Elle à l’air énorme ta technique !
    Et le tuto est vraiment clair, je vais essayer ça dès que possible…

    Je reste assez sceptique sur le comportement de certains plugins par contre…

  4. DrKokai
    4 messages

    DrKokai - Le 31 mai 2012, 09:45

    Hello,

    J’aurais bientôt 4 sites et j’aimerai avoir qu’un back office pour les 4 et pouvoir les gérer depuis la même place.
    Est ce possible?

  5. Fredo
    1 message

    Fredo - Le 31 mai 2012, 10:08

    Tres intéressant ! Mais quid de cette modification lors des prochaines mises à jour de WordPress ? Devra-t-on tout recommencer ou pas ?

  6. Diije
    16 messages

    Diije - Le 31 mai 2012, 10:12

    Une astuce utile en effet, même si à mon humble avis un htpassword sur wp-login.php et le répertoire wp-admin suffit à repousser pas mal d’attaques.

  7. Soul
    5 messages

    Soul - Le 31 mai 2012, 12:04

    C’est quand même super mal fait, j’aurais pensé pouvoir changer le nom du répertoire sans problèmes mais non.
    En espérant qu’un WP_BASE_ADMIN apparaisse un jour…

  8. Lionel Pointet
    3 messages

    Lionel Pointet - Le 31 mai 2012, 14:12

    @tous : merci pour avoir lu et apparemment apprécié l’article.

    @Willy : je suis également très prudent quant à l’utilisation de cette technique avec des plugins, il faut bien vérifier que rien n’est dégradé avant de mettre le tout en production.

    @DrKokai : ce n’était pas l’objectif de l’article mais tu peux soit utiliser la fonctionnalité Multisite de WordPress (http://codex.wordpress.org/Create_A_Network), soit utiliser une application tierce comme ManageWP (http://wpmagazine.fr/managewp-gerer-simultanement-plusieurs-sites-wordpress/).

    @Fredo : comme expliqué, la seule contrainte par rapport à l’arborescence de base de WordPress est le fichier wp-login.php déplacé. Vu que c’est un fichier ajouté par rapport aux autres, les mises à jour ne le suppriment pas et ne l’écrasent pas non plus. Pour le reste, ce sont des filtres qui peuvent être inclus dans un thème ou un plugin donc aucun risque.

    @Diije : le but de la manipulation n’était pas la sécurité, mais la répartition de charge : on voulait que ce soit un seul serveur qui gère toute l’administration et qu’il soit différent de ceux qui gèrent le front. On peut désormais rediriger le sous-domaine vers ce serveur en particulier.
    Pour la sécurité, il y a déjà des restricitions par IP sur le dossier wp-admin, donc aucun soucis de ce côté-là ;).

  9. DrKokai
    4 messages

    DrKokai - Le 31 mai 2012, 15:35

    Hello,

    Je passais par là et administration => administration alors j’ai poser un comment!
    Merci, pour ta réponse

  10. Screenfeed
    17 messages

    Screenfeed - Le 01 juin 2012, 02:57

    Salut.

    Bravo, belle astuce, et le tout sans toucher au core.
    Je pense que ça ne posera pas de problème avec la majorité des plugins (du moins, ceux qui sont encore « en activité », c’est à dire mis à jour régulièrement), mais en effet il vaut mieux vérifier à chaque fois.

    Bien vu pour l’ajax. Si j’avais tenté une telle manip (ce qui n’est pas vraiment dans mes cordes quand même ^^), il m’aurait fallut un bon moment pour comprendre que l’ajax ne fonctionnait plus à cause du cross-domain (oui, je joue rarement entre plusieurs domaines, donc j’y pense jamais ^^). Et pour les cookies en… j’aurais jamais trouvé la solution je pense haha.

    Bref, jolie manip’, merci pour le partage :)

  11. Keeg
    20 messages

    Keeg - Le 01 juin 2012, 19:31

    Je prends, je crois que ça va servir pas mal d’entre nous sur des projets sensibles.

  12. mickaël andrieu
    1 message

    mickaël andrieu - Le 01 juin 2012, 21:01

    Impressionnant :) ça me rappelle tout bas que je suis encore loin de maîtriser WordPress tant ses possibilités sont exceptionnelles (un moteur de blog, comme me disaient mes profs ^^)

  13. champagne
    1 message

    champagne - Le 21 juillet 2012, 13:22

    Effectivement, c’est une manipulation très délicate…

    Je pense surtout que ce déplacement va accroitre la sécurité et minimiser les risque de piratage par des petit bidouilleur de dimanche, ça les perturbera.

    Et merci pour ce petit tuto, je vais déjà tester ça en local avant car je suis pas très bon pour bidouiller les codes.

    Merci encore et dès que j’ai déplacé mon back office je vous tient au courant !

  14. JB
    2 messages

    JB - Le 30 septembre 2013, 03:00

    Pas tres utile et risque de cassez beaucoup de chose dans le fonctionnement meme de wp le plus simple est de sécurisé les page wp login wp admin et autre de cette maniere en passant par le ht access :

    [DERCRIPTION DU FONCTIONNEMENT}
    - mot-au-choix-login = un mot au choix qui remplacera /wp-login.php
    - mot-au-choix-admin = un mot au choix qui remplacera /wp-admin
    - mot-au-choix-nouvel_utilisateur = un mot au choix qui remplacera la page d'enregistrement d'un nouvel utilisateur
    - CLEF = une suite de lettre et de nombre au choix de préférence assez longue (20 caractère minimum)
    URL-DE-VOTRE-SITE = url de votre site

    # CACHER LOGIN, REGISTER, ADMIN
    # wp-login = mot-au-choix-login
    RewriteRule ^mot-au-choix-login/?$ /wp-login.php?CLEF [R,L]
    # wp-admin = mot-au-choix-admin
    RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in_.*$
    RewriteRule ^mot-au-choix-admin/?$ /wp-login.php?CLEF&redirect_to=/wp-admin/ [R,L]
    #
    RewriteRule ^mot-au-choix-admin/?$ /wp-admin/?CLEF [R,L]
    # wp-login register = mot-au-choix-nouvel_utilisateur
    RewriteRule ^mot-au-choix-nouvel_utilisateur/?$ /wp-login.php?CLEF&action=register [R,L]
    #
    RewriteCond %{SCRIPT_FILENAME} !^(.*)admin-ajax\.php
    RewriteCond %{HTTP_REFERER} !^(.*)URL-DE-VOTRE-SITE/wp-admin
    RewriteCond %{HTTP_REFERER} !^(.*)URL-DE-VOTRE-SITE/wp-login\.php
    RewriteCond %{HTTP_REFERER} !^(.*)URL-DE-VOTRE-SITE/mot-au-choix-login
    RewriteCond %{HTTP_REFERER} !^(.*)URL-DE-VOTRE-SITE/mot-au-choix-admin
    RewriteCond %{HTTP_REFERER} !^(.*)URL-DE-VOTRE-SITE/mot-au-choix-nouvel_utilisateur
    RewriteCond %{QUERY_STRING} !^CLEF
    RewriteCond %{QUERY_STRING} !^action=logout
    RewriteCond %{QUERY_STRING} !^action=rp
    RewriteCond %{QUERY_STRING} !^action=register
    RewriteCond %{QUERY_STRING} !^action=postpass
    RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in_.*$
    # Si tentative d&rsquo;entrer sur les ancienne url message : try_again
    RewriteRule ^.*wp-admin/?|^.*wp-login\.php /try_again [R,L]
    #
    RewriteCond %{QUERY_STRING} ^loggedout=true
    RewriteRule ^.*$ /wp-login.php?CLEF [R,L]

    une fois les changements effectué dans votre fichier htaccess il faudra alors vous connecter a l'adresse :
    votre-site.com/mot-au-choix-login

    Have FUN

» Commentez cet article !
(Merci de donner un vrai prénom)
(Ne sera jamais publié)
(Modèration subjective)
Html accepté <a> <i> <b> [codesyntax]CODE[/codesyntax]
» Prévisualisez votre message

© 2010-2012 SeoMix : WordPress & Référencement
Propulsé par WordPress et Daniel Roch. Logo créé par Willy-Bahuaud

Indispensable
WordPress
A propos de SeoMix
Mes servicesWordPress - Référencement
Suivez-nous !
  • 8813 abonnés
  • 197 articles
  • 4604 messages
Vous devriez lire
Seo et emarketing
Les amis
271ffc2ef149358fd5dfa20779d60c5eGGGGGGGGG