# 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.

- Auteur : WordPress Développement
- Publié le : 2021-10-30
- Mis à jour le : 2021-10-30
- Catégorie : Headless &amp; API
- URL : https://www.wpmoderne.fr/headless/desactiver-wp-admin-garder-rest-api-active/

## L’essentiel

- 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

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.
