Flutter & développement mobile
Connecter une application Flutter à WordPress : API REST, JWT et endpoints sur mesure
Pour connecter Flutter à WordPress, faites de WordPress un back-office qui expose des données JSON via son API REST, avec des endpoints sur mesure déclarés par register_rest_route(). L’application s’authentifie par un jeton envoyé dans l’en-tête Authorization, isole ses appels dans une couche de services, et l’API reste rapide grâce au cache et fermée par défaut.
Flutter, WordPress et l’API REST forment l’architecture que j’utilise chez AppliWin pour les applications de mes clients : WordPress gère les contenus, les utilisateurs et les paiements ; Flutter affiche tout cela sur iOS et Android avec un seul code. Ce guide détaille les choix techniques d’une intégration propre, de l’architecture à la sécurité, tirés d’un projet réel en production. Si vous cherchez un prestataire plutôt qu’un tutoriel, ma page WordPress headless et API REST présente l’offre complète.
Architecture : WordPress en back-office de l’application mobile, Flutter en interface
Dans une architecture découplée, WordPress ne sert plus de pages à l’application : il expose des données JSON via l’API REST de WordPress, sous /wp-json/. L’app Flutter interroge ces routes, conserve un jeton d’authentification et affiche des écrans natifs. Le même back-office alimente le site web et les deux applications : un seul back-office, deux plateformes.
Concrètement, l’architecture tient en quatre couches, chacune avec une responsabilité claire :
WordPress
Types de contenus, champs personnalisés, utilisateurs, WooCommerce : la source de vérité.
Couche API
Un plugin dédié déclare un namespace propre à l’app, des routes et leurs permissions.
Transport
HTTPS, réponses JSON compactes, jeton dans l’en-tête Authorization.
Flutter
Services réseau, modèles Dart typés, gestion d’état, cache local, écrans natifs.
Sur l’application LSF-CFB, cette séparation se lit directement dans le code : un namespace dédié regroupe l’authentification, les cours, les abonnements, les favoris, la gamification et le forum. L’app Flutter n’appelle jamais les pages du site ; elle ne parle qu’à ces routes. Le site de présentation de l’application, lui, vit sur le même WordPress.
Endpoints personnalisés : ne pas se contenter de /wp/v2
Les routes natives comme /wp/v2/posts renvoient beaucoup de champs inutiles et obligent l’app à multiplier les appels. Un endpoint sur mesure, déclaré avec register_rest_route() dans un plugin, renvoie exactement ce dont un écran a besoin : un cours avec sa progression, ses vidéos et les droits d’accès de l’utilisateur, en une seule requête.
L’API native de WordPress reste utile pour des contenus simples, et son paramètre _fields permet déjà d’alléger les réponses. Mais dès que l’application affiche des données croisées (un contenu, une progression, un abonnement), les endpoints sur mesure deviennent indispensables. Ils se déclarent avec register_rest_route(), sous un namespace versionné du type monapp/v1, avec une route comme /courses/(?P<id>\d+).
| Critère | Routes natives /wp/v2 | Endpoints sur mesure |
|---|---|---|
| Mise en place | Immédiate | Développement d’un plugin |
| Forme des réponses | Imposée par WordPress, verbeuse | Pensée pour chaque écran |
| Nombre d’appels par écran | Souvent plusieurs | Un seul en général |
| Logique métier (droits, progression, abonnement) | À reconstituer dans l’app | Calculée côté serveur |
| Stabilité pour l’app | Dépend des évolutions de WordPress et des plugins | Contrat versionné (v1, v2) |
Les règles d’un bon endpoint
- Code placé dans un plugin, pas dans le thème : l’API survit à un changement de design.
- Une
permission_callbacksur chaque route : WordPress la considère comme obligatoire depuis la version 5.5. - Paramètres déclarés dans
args, avec validation et assainissement systématiques. - Réponses stables et versionnées : un champ renommé casse les apps déjà installées.
- Pagination explicite et nombre total d’éléments renvoyé, pour les listes longues.
Authentification JWT avec WordPress, Application Passwords ou jeton maison
Une application mobile ne peut pas utiliser les cookies et nonces de WordPress. Il lui faut un jeton (un JWT fourni par un plugin éprouvé, ou un jeton émis par un endpoint de connexion sur mesure), transmis dans l’en-tête Authorization: Bearer. Les Application Passwords de WordPress, natifs depuis la version 5.6, servent aux outils internes, pas à vos utilisateurs.
| Méthode | Principe | Usage conseillé |
|---|---|---|
| Cookie + nonce | Session du navigateur connecté au site | Front-end web uniquement, pas d’app mobile |
| Application Passwords | Mot de passe dédié par application, envoyé en Basic Auth sur HTTPS | Scripts, intégrations, outils internes |
| JWT | Jeton signé avec une durée de vie, obtenu à la connexion | Comptes utilisateurs d’une app grand public |
| Jeton opaque maison | Jeton aléatoire stocké côté serveur, révocable à tout moment | Apps qui exigent une révocation immédiate |
Le parcours type : l’app envoie l’e-mail et le mot de passe à une route de connexion, reçoit un jeton, le range dans le stockage sécurisé du téléphone (Keychain sur iOS, Keystore sur Android, via le package flutter_secure_storage) et l’ajoute à chaque requête. Sur une réponse 401, l’app tente un rafraîchissement ou renvoie vers l’écran de connexion. Sur LSF-CFB, le jeton reçu à la connexion est conservé dans ce stockage sécurisé et envoyé dans l’en-tête Bearer de chaque appel.
- Durée de vie courte pour le jeton d’accès, avec un jeton de rafraîchissement pour éviter de redemander le mot de passe.
- Clé secrète dans
wp-config.php, jamais dans le dépôt de code ni dans l’application. - Aucune donnée sensible dans un JWT : son contenu est simplement encodé, lisible par quiconque l’intercepte.
- Révocation : un JWT reste valide jusqu’à son expiration. Un numéro de version par utilisateur, vérifié côté serveur, permet de tout invalider après un changement de mot de passe.
Un cas particulier fréquent : WooCommerce. Ses clés d’API (consumer key et consumer secret) donnent accès à toute la boutique. Elles ne doivent jamais être embarquées dans une application, car elles s’extraient du binaire en quelques minutes. L’app appelle vos propres endpoints, qui agissent au nom de l’utilisateur connecté et seulement sur ses données.
Côté Flutter : une couche réseau propre et testable
Côté Flutter, isolez tous les appels réseau dans une couche de services : un client http ou dio, des modèles Dart typés, une gestion centralisée des erreurs 401 et des délais d’attente, et une gestion d’état (Provider, Riverpod ou BLoC) qui ne connaît jamais les URL. L’app reste testable et le back-office peut évoluer sans tout casser.
- URL de l’API par environnement (recette, production), injectée à la compilation avec
--dart-define. - Délais d’attente et nouvelles tentatives sur les erreurs réseau, jamais sur les erreurs métier.
- Désérialisation des grosses listes hors du fil principal pour garder une interface fluide.
- Images mises en cache sur l’appareil, dimensionnées côté serveur.
- Cache local des contenus déjà consultés pour le mode hors ligne, synchronisé au retour du réseau.
La vidéo mérite une attention à part. Sur LSF-CFB, les vidéos sont réencodées côté serveur en H.264, en 720p, pour rester lisibles sur l’ensemble du parc Android, y compris les appareils modestes. L’API renvoie l’URL du fichier optimisé, qui garde la même adresse ; l’app se charge de la lecture en streaming et affiche un message clair si une vidéo ne peut pas être lue. Reprendre la lecture là où l’utilisateur s’était arrêté demande en plus d’enregistrer sa position : une évolution simple sur ce socle.
Cache, performance et sécurité de l’API
Une API WordPress exposée à une application doit être rapide et fermée par défaut. Mettez en cache les réponses publiques, limitez les champs renvoyés, protégez chaque route par une permission_callback stricte, imposez HTTPS, limitez le débit des routes sensibles et neutralisez les routes inutiles, comme la liste publique des utilisateurs.
Cache et performance
- Cache objet (Redis ou Memcached) pour les requêtes lourdes, et transients pour les calculs coûteux.
- En-têtes HTTP
Cache-ControletETagsur les routes publiques, pour éviter de renvoyer ce que l’app possède déjà. - Cache de pages : le comportement varie selon l’extension. LiteSpeed Cache, par exemple, met l’API REST en cache par défaut, d’autres l’ignorent. Vérifiez le réglage, mettez en cache les routes publiques et excluez toujours les routes authentifiées.
- Requêtes SQL : un endpoint mal écrit qui boucle sur des métadonnées peut multiplier les requêtes. Mesurez avant de mettre en production.
Sécurité
- HTTPS obligatoire, sans exception, y compris en recette.
- Une permission_callback réelle sur chaque route privée ;
__return_trueseulement pour des données publiques. - Limitation du nombre de tentatives sur la route de connexion contre la force brute.
- Route
/wp/v2/usersrestreinte pour empêcher l’énumération des comptes. - Validation côté serveur de tout ce qui a une valeur : achats intégrés, droits d’accès, progression.
- Journalisation des erreurs d’API, sans jamais y écrire de jeton ni de mot de passe.
Sur le point des achats intégrés, la règle est simple : un reçu d’achat Apple ou Google se vérifie sur le serveur, auprès des API des stores, avant d’ouvrir un accès. Une app qui se contente de dire « l’utilisateur a payé » se contourne facilement. Enfin, le CORS ne concerne que les navigateurs : une app native n’en a pas besoin, une version Flutter Web si.
À retenir
WordPress fait un excellent back-office d’application à trois conditions : des endpoints sur mesure dans un plugin, une authentification par jeton stocké de façon sécurisée, et une API fermée par défaut. Le reste, c’est du cache et de la discipline.
Questions fréquentes
WordPress peut-il servir de back-office à une application mobile ?
Oui, et c’est souvent le choix le plus économique quand un site WordPress existe déjà. Vos équipes gardent une administration qu’elles connaissent, les contenus sont partagés entre le site et l’application, et WooCommerce gère les commandes et les abonnements. Il faut en revanche une couche d’API sur mesure, une authentification par jeton et un hébergement dimensionné pour absorber le trafic de l’application en plus de celui du site.
Faut-il un plugin JWT pour connecter Flutter à WordPress ?
Pas forcément. Un plugin JWT éprouvé fait gagner du temps et convient à beaucoup de projets. Un endpoint de connexion sur mesure, qui émet son propre jeton, offre plus de contrôle : durée de vie, révocation, données renvoyées à la connexion. Dans les deux cas, l’important est le reste de la chaîne : stockage sécurisé sur le téléphone, HTTPS, permissions vérifiées côté serveur sur chaque route.
API REST ou WPGraphQL pour une application Flutter ?
WPGraphQL permet à l’application de demander exactement les champs voulus et convient bien aux écrans très variés. L’API REST, native dans WordPress, est plus simple à mettre en cache, à sécuriser route par route et à faire évoluer avec des endpoints métier. Pour une application avec paiements, droits d’accès et logique propre, je privilégie des endpoints REST sur mesure, qui encapsulent cette logique côté serveur.
Peut-on utiliser l’API WooCommerce directement depuis l’application Flutter ?
Pas avec les clés d’API WooCommerce : elles donnent accès à toute la boutique et ne doivent jamais se trouver dans une application, car elles peuvent en être extraites. La bonne approche consiste à exposer des endpoints sur mesure qui utilisent les fonctions de WooCommerce côté serveur, au nom de l’utilisateur connecté et uniquement sur ses propres commandes, abonnements et données.
Construire votre application sur votre WordPress
Brancher Flutter sur WordPress via l’API REST, c’est garder un seul back-office pour le site et les applications iOS et Android, à condition de traiter l’API comme un produit à part entière. Si vous hésitez encore entre une simple WebView et une vraie app, lisez transformer son site WordPress en application ; si c’est la technologie qui vous fait douter, voyez Flutter ou React Native. Pour un projet d’application mobile WordPress, demandez un devis : le cadrage est gratuit.