Les API web modernes (service workers, géolocalisation, presse-papiers, caméra) nécessitent HTTPS — même pendant le développement. Ce guide explique comment obtenir un HTTPS de confiance sur localhost sans avertissements du navigateur.
Pourquoi vous ne pouvez pas utiliser Let’s Encrypt pour localhost
Let’s Encrypt valide la propriété du domaine en vérifiant un fichier sur votre serveur ou un enregistrement DNS. localhost n’est pas un vrai domaine — il résout en 127.0.0.1 uniquement sur votre machine. Personne ne peut vérifier que vous « possédez » localhost, donc aucune CA publique n’émettra de certificat pour celui-ci.
Vos options pour le HTTPS sur localhost :
- mkcert — crée des certificats de confiance localement (recommandé)
- Certificat auto-signé — fonctionne mais affiche des avertissements du navigateur
- Service de tunneling — ngrok, Cloudflare Tunnel (vrai domaine, vrai certificat)
Option 1 : mkcert (recommandé)
mkcert crée une Autorité de Certification locale sur votre machine, l’ajoute au magasin de confiance de votre système et émet des certificats signés par cette CA. Les navigateurs font confiance à ces certificats sans avertissements.
Installer mkcert
# macOS
brew install mkcert
# Linux (nécessite libnss3-tools pour Firefox)
sudo apt install libnss3-tools
brew install mkcert # ou télécharger depuis les releases GitHub
# Windows
choco install mkcert
# ou : scoop install mkcert
Configurer la CA locale
mkcert -install
# Sortie : Created a new local CA
# La CA locale est maintenant installée dans le magasin de confiance du système
Cela ajoute un certificat racine aux magasins de confiance de votre système et de votre navigateur. Faites-le une seule fois — cela fonctionne pour tous les futurs certificats.
Générer des certificats
# Pour localhost
mkcert localhost 127.0.0.1 ::1
# Pour un domaine local personnalisé
mkcert myapp.test "*.myapp.test" localhost 127.0.0.1
# Sortie :
# Created a new certificate valid for the following names:
# - "localhost"
# - "127.0.0.1"
# - "::1"
# The certificate is at "./localhost+2.pem" and the key at "./localhost+2-key.pem"
Utiliser avec votre serveur de développement
Node.js/Express :
const https = require('https');
const fs = require('fs');
const app = require('./app');
https.createServer({
key: fs.readFileSync('./localhost+2-key.pem'),
cert: fs.readFileSync('./localhost+2.pem'),
}, app).listen(3000);
Nginx (local) :
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /path/to/localhost+2.pem;
ssl_certificate_key /path/to/localhost+2-key.pem;
# ...
}
Vite / webpack dev server :
// vite.config.js
import fs from 'fs';
export default {
server: {
https: {
key: fs.readFileSync('./localhost+2-key.pem'),
cert: fs.readFileSync('./localhost+2.pem'),
},
},
};
Avertissement de sécurité
Ne partagez jamais la clé racine CA de mkcert (rootCA-key.pem dans mkcert -CAROOT). Quiconque la possède peut créer des certificats de confiance pour n’importe quel domaine sur votre machine — essentiellement une capacité locale de type man-in-the-middle.
mkcert est uniquement pour le développement. Pour la production, utilisez Let’s Encrypt.
Option 2 : Certificat auto-signé
Si vous ne pouvez pas installer mkcert, générez un certificat auto-signé avec OpenSSL :
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 \
-keyout localhost-key.pem -out localhost-cert.pem \
-days 365 -nodes -subj "/CN=localhost" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
Inconvénient : Les navigateurs affichent un avertissement de sécurité car les certificats auto-signés ne sont reconnus par aucune CA. Vous devrez passer l’avertissement à chaque fois (ou ajouter une exception).
Option 3 : Tunneling (vrai domaine + vrai certificat)
Utilisez un service de tunneling pour exposer votre serveur local avec un vrai domaine et un vrai certificat :
# ngrok
ngrok http 3000
# Vous donne : https://abc123.ngrok.io
# Cloudflare Tunnel
cloudflared tunnel --url http://localhost:3000
# Vous donne : https://random-name.trycloudflare.com
Quand c’est pertinent : tester des webhooks, partager avec un collègue, tester des callbacks OAuth qui nécessitent HTTPS.
mkcert vs auto-signé vs tunneling
| mkcert | Auto-signé | Tunneling | |
|---|---|---|---|
| Avertissements navigateur | Aucun | Oui (chaque session) | Aucun |
| Effort de configuration | Faible (une installation) | Faible (une commande) | Faible |
| Fonctionne hors ligne | Oui | Oui | Non |
| Performance | Vitesse locale | Vitesse locale | Latence réseau |
| Domaines personnalisés | Oui (*.test, etc.) | Oui | Attribué par le fournisseur |
| Idéal pour | Développement quotidien | Test ponctuel rapide | Webhooks, partage |
Questions fréquentes
Puis-je utiliser le même certificat mkcert dans toute mon équipe ?
Ne partagez pas la clé racine CA. Chaque développeur devrait exécuter mkcert -install sur sa propre machine pour créer sa propre CA locale. Vous pouvez partager les certificats générés (les fichiers .pem), mais chaque personne doit avoir la CA installée pour leur faire confiance.
mkcert fonctionne-t-il avec Docker ?
Oui. Montez les fichiers de certificat dans le conteneur et référencez-les dans la configuration du serveur. Le conteneur lui-même n’a pas besoin d’avoir mkcert installé — juste les fichiers .pem. Votre machine hôte (où le navigateur s’exécute) doit avoir la CA mkcert installée.
Quel domaine local devrais-je utiliser ?
Utilisez .test (ex. : myapp.test) — il est réservé par l’IETF pour les tests et n’entrera jamais en conflit avec un vrai domaine. Évitez .dev (appartient à Google) et .local (utilisé par mDNS). Ajoutez une entrée dans /etc/hosts pour pointer votre domaine .test vers 127.0.0.1.
Comment passer du HTTPS localhost au HTTPS de production ?
Ils sont complètement séparés. Votre certificat localhost (mkcert/auto-signé) reste sur votre machine de développement. Pour la production, obtenez un vrai certificat de Let’s Encrypt via GetHTTPS. Votre code devrait lire les chemins de certificats depuis des variables d’environnement pour que le changement ne soit qu’une modification de configuration.