Ingénierie 28 juillet 2026 · 6 min de lecture

Un contrôle d'accès par QR qui marche même sans internet : comment on l'a bâti pour FitSen

À Dakar, l'internet tombe et le courant saute. Un portique qui refuse d'ouvrir parce que « le serveur ne répond pas » n'est pas une option. Voici comment on a conçu l'accès de FitSen pour qu'il fonctionne même déconnecté — sans sacrifier la sécurité.

Dans une salle de sport à Dakar, l’accueil est un goulot d’étranglement. À 18 h, tout le monde arrive en même temps. La personne à la réception doit reconnaître le membre, vérifier que son abonnement est à jour, et le laisser entrer — vite. Si en plus le logiciel dépend d’une connexion internet qui coupe trois fois par jour, la file s’allonge et la frustration monte.

Quand on a conçu le contrôle d’accès de FitSen, on a posé une contrainte non négociable dès le départ : le portique doit ouvrir même quand le réseau est mort. Pas « se dégrader gracieusement ». Ouvrir. Un membre à jour qui présente son code à 18 h 03, au moment précis où la 4G du quartier tousse, doit entrer comme si de rien n’était.

Cet article raconte comment on y est arrivé, et pourquoi certains choix qui semblent contre-intuitifs sont en réalité les seuls qui tiennent sur le terrain.

Le vrai problème n’est pas le QR, c’est la confiance hors ligne

Afficher un QR code sur le téléphone d’un membre, c’est trivial. La difficulté est ailleurs : comment le lecteur à l’entrée décide-t-il, seul, si ce code est valide ?

L’approche naïve consiste à mettre un identifiant dans le QR (« membre n°4128 »), puis à demander au serveur : « est-ce que 4128 a le droit d’entrer ? ». Simple, mais fatal ici. Dès que la connexion tombe, le lecteur devient aveugle. Et un identifiant en clair, c’est aussi un code qu’on recopie, qu’on partage sur WhatsApp, qu’on prête à un ami.

On voulait l’inverse : un lecteur capable de vérifier lui-même la validité d’un code, sans appeler personne, tout en rendant le code impossible à falsifier ou à réutiliser.

Signer plutôt qu’interroger

La brique centrale est la signature cryptographique. Plutôt qu’un identifiant nu, le QR contient une petite charge signée par le serveur : ce membre, cette salle, cet instant. On utilise des signatures Ed25519 — rapides, courtes, robustes.

Le mécanisme tient en trois idées :

  • Le serveur détient une clé privée et signe les jetons d’accès.
  • Chaque lecteur (le kiosque à l’entrée) embarque la clé publique correspondante.
  • Vérifier une signature ne demande aucun réseau : c’est un calcul local, quelques millisecondes.

Résultat : le kiosque peut confirmer qu’un code a bien été émis par FitSen, pour cette salle, sans jamais parler au serveur au moment du scan. La confiance est pré-chargée dans l’appareil, pas quémandée à chaque entrée.

La règle qu’on s’est fixée : au moment critique — quelqu’un devant le portique — aucune décision ne doit dépendre d’un aller-retour réseau.

Empêcher la capture d’écran : le code qui tourne

Un QR statique a un défaut évident : on le photographie une fois, et on le renvoie à dix personnes. Pour un abonnement individuel, c’est une fuite directe de revenus.

La parade : le code tourne. Le QR affiché dans l’app membre — le FitSen Pass — se régénère à intervalle court. Chaque jeton porte un horodatage et n’est accepté que dans une fenêtre de quelques secondes. Une capture d’écran envoyée à un ami est déjà périmée quand il arrive à la salle.

Cela crée une tension technique intéressante : le membre, lui aussi, peut être hors ligne quand il ouvre son app dans le hall. Le Pass devait donc pouvoir générer des codes valides sans connexion, de son côté, tout en restant synchronisé avec ce que le kiosque attend. On a résolu ça avec un secret provisionné à l’avance sur l’appareil du membre et une horloge partagée — le téléphone dérive un nouveau code localement, le kiosque le valide localement. Deux appareils déconnectés qui tombent quand même d’accord.

Lier le pass à l’appareil

Signer et faire tourner le code règle la falsification et la rediffusion en masse. Restait le prêt « à l’ancienne » : je donne mon téléphone à quelqu’un. Là, aucune cryptographie ne peut décider à votre place — c’est une question de politique, pas de maths.

Ce qu’on fait, c’est lier le pass à l’appareil sur lequel il a été activé. Utiliser le Pass sur un nouveau téléphone demande une ré-activation. On ne cherche pas à rendre la fraude impossible — c’est illusoire — mais à la rendre plus pénible que de payer son abonnement. C’est le bon curseur pour une salle de sport : décourager le partage courant, sans transformer chaque entrée en interrogatoire.

Le kiosque : une PWA qui n’a pas peur du noir

Le lecteur à l’entrée est une application web installable (PWA), pensée pour tourner sur du matériel modeste — une tablette, un vieux téléphone monté sur pied. Ce choix nous a beaucoup coûté en rigueur, et beaucoup rapporté en robustesse :

  • Elle met en cache tout ce dont elle a besoin pour fonctionner : la clé publique, la liste des membres et de leurs droits, l’interface.
  • Elle enregistre les entrées localement quand le réseau est absent, puis les rejoue vers le serveur dès qu’il revient. Aucune entrée n’est perdue, même pendant une coupure d’une heure.
  • Elle affiche un verdict immédiat et lisible à un mètre : vert on entre, rouge on s’arrête. Pas de roue qui tourne, pas de « veuillez patienter ».

C’est là que le principe offline-first prend tout son sens : on ne branche pas un mode dégradé sur une app en ligne. On construit l’app pour le hors-ligne, et la connexion devient un bonus qui sert à synchroniser en arrière-plan.

Les tourniquets, sans se marier à un fournisseur

Beaucoup de salles veulent un vrai portique physique, pas seulement un vigile avec une tablette. Le piège serait de coder en dur l’intégration d’une marque de tourniquet précise, et de se retrouver prisonnier de ce choix.

On a préféré exposer le résultat de la décision d’accès comme un signal simple et neutre : accès autorisé, accès refusé. Un relais qui déclenche l’ouverture. Cette frontière propre nous permet de brancher des matériels différents sans toucher au cœur de FitSen — et de commencer petit (un scan validé par un membre du staff) avant d’investir dans du portique motorisé.

Ce que ce projet nous a appris

Trois convictions sont ressorties renforcées de ce chantier :

  1. La contrainte réseau n’est pas un cas limite ici, c’est le cas normal. Concevoir pour le hors-ligne dès la première ligne de code donne un produit plus simple et plus solide que rajouter un « mode offline » après coup.
  2. La cryptographie déplace la confiance au bon endroit. Signer les jetons transforme chaque lecteur en juge autonome. C’est ce qui rend le hors-ligne possible sans ouvrir la porte à la fraude.
  3. La sécurité parfaite n’existe pas, et ce n’est pas l’objectif. Le bon curseur, c’est de rendre la triche plus coûteuse que l’honnêteté. Pour un accès de salle de sport, c’est amplement suffisant.

FitSen est en production, utilisé au Sénégal. Le contrôle d’accès en fait partie, et il continue de tourner quand la connexion, elle, s’arrête.


Vous construisez un produit qui doit résister aux réalités du terrain africain — coupures, cash, WhatsApp ? Parlons-en.

À lire aussi

Un problème concret à résoudre ?

On observe, on construit, on opère — parlons du vôtre.

Discutons de votre projet