Le WordPress d'aujourd'hui, décodé pour les développeurs

Headless & API

Désactiver wp-admin tout en gardant la REST API pleinement active

Là où un rideau de fer bloquerait aussi les requêtes JSON, une redirection ciblée sur wp-admin laisse l'API REST fonctionner sans la moindre interruption.

Par WordPress Développement • 30 octobre 2021 • 4 min de lecture • Aucun commentaire
Désactiver wp-admin tout en gardant la REST API pleinement active

Bloquer l’accès à wp-admin ressemble à une opération simple : une redirection, une vérification de rôle, et le tour est joué. Bloquer wp-admin tout en laissant l’API REST parfaitement fonctionnelle est une opération légèrement plus délicate, car les deux chemins ne partagent qu’une partie de leur cycle d’exécution WordPress, et une redirection mal ciblée referme les deux portes à la fois sans qu’on s’en rende compte immédiatement.

Pourquoi la distinction est nécessaire

Sur un projet headless où le contenu est entièrement piloté depuis un outil de gestion tiers ou depuis un accès restreint, l’interface d’administration classique de WordPress devient superflue pour la majorité des utilisateurs, voire une surface d’attaque à réduire. Fermer wp-admin à toute personne non autorisée, tout en laissant l’API REST répondre normalement aux requêtes légitimes du front, permet de réduire cette surface sans perdre la capacité du front à consommer les données.

Le point de vigilance principal tient au hook utilisé pour appliquer cette restriction. Une requête REST ne charge jamais wp-admin, mais elle traverse tout de même une partie du chargement de WordPress commune aux deux univers, notamment le hook init. Une condition posée trop largement, ou accrochée au mauvais moment, peut casser les deux chemins simultanément.

La recette

L'essentiel à retenir : template_redirect ne s'exécute jamais sur une requête REST ; Une redirection large peut couper wp-admin sans toucher à /wp-json/ ; Le mécanisme d'authentification de l'API reste séparé de la session admin
add_action( 'init', function () {
    $est_requete_rest = defined( 'REST_REQUEST' ) && REST_REQUEST;
    $est_ajax         = wp_doing_ajax();
    $est_admin        = is_admin();

    if ( $est_admin && ! $est_requete_rest && ! $est_ajax && ! current_user_can( 'manage_options' ) ) {
        wp_safe_redirect( home_url( '/' ) );
        exit;
    }
} );

La constante REST_REQUEST, définie par WordPress dès qu’une requête transite par le serveur REST, permet de distinguer sans ambiguïté ce contexte du reste de l’exécution. La fonction is_admin(), elle, ne vérifie absolument pas un rôle utilisateur : elle indique seulement que la requête courante cible une URL de wp-admin, qu’il s’agisse d’un affichage de page ou d’une requête admin-ajax.php. C’est justement pour cette raison que wp_doing_ajax() doit être vérifié séparément, faute de quoi certains appels internes de l’éditeur de blocs, qui transitent par admin-ajax.php, se retrouveraient bloqués à tort.

Ce qui reste accessible

  • Toutes les routes de /wp-json/, y compris celles ajoutées par des extensions tierces
  • La page de connexion wp-login.php, nécessaire pour que les utilisateurs autorisés puissent encore s’identifier
  • L’accès complet à wp-admin pour tout utilisateur disposant de la capacité manage_options, généralement réservée aux administrateurs

Un piège fréquent : bloquer trop tôt

Accrocher cette vérification à un hook qui s’exécute avant que les capacités utilisateur ne soient pleinement disponibles — trop tôt dans le cycle de chargement de WordPress — produit un comportement erratique, où current_user_can() retourne systématiquement faux même pour un administrateur légitime déjà connecté. Le hook init reste un choix sûr, car il se déclenche après l’initialisation complète de l’utilisateur courant, contrairement à des hooks plus précoces comme plugins_loaded.

Vérifier que l’API reste bien intacte

Une fois la restriction en place, un test simple consiste à interroger une route publique de l’API REST depuis un terminal, sans être authentifié, et à vérifier que la réponse JSON attendue arrive normalement, avec un statut 200 :

curl -i https://exemple.test/wp-json/wp/v2/posts

Si cette commande retourne une redirection vers la page d’accueil plutôt que le JSON attendu, la condition posée sur init est probablement trop large et capture aussi les requêtes REST, signe qu’il faut revérifier la constante REST_REQUEST utilisée dans la condition.

En résumé

Fermer wp-admin sans toucher à l’API REST tient à une seule distinction technique : la constante REST_REQUEST permet de reconnaître à coup sûr un appel à l’API, indépendamment du reste de la logique de restriction posée sur wp-admin. Une fois cette distinction posée correctement, un projet headless peut réduire drastiquement sa surface d’administration exposée sans jamais perturber le fonctionnement du front qui consomme ses données.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi