Aller au contenu principal

Variables d'environnement

Notions théoriques

Pourquoi les variables d'environnement ?

Les variables d'environnement permettent de séparer la configuration du code. On ne met jamais de mots de passe, d'URL de base de données ou de clés API directement dans le code source.

// MAUVAIS — mot de passe dans le code !
string mdp = "MonMotDePasse123";

// BON — mot de passe dans l'environnement
string? mdp = Environment.GetEnvironmentVariable("DB_PASSWORD");

Définir des variables d'environnement

Sur Windows (PowerShell) :

# Temporaire (session courante uniquement)
$env:DB_HOST = "localhost"
$env:DB_PASSWORD = "secret"

# Permanent (utilisateur courant)
[System.Environment]::SetEnvironmentVariable("DB_HOST", "localhost", "User")

Sur Linux (Bash) :

# Temporaire (session courante)
export DB_HOST="localhost"
export DB_PASSWORD="secret"

# Permanent (ajouter dans ~/.bashrc ou ~/.zshrc)
echo 'export DB_HOST="localhost"' >> ~/.bashrc

Lire les variables d'environnement en C#

// Lecture simple (retourne null si non définie)
string? host = Environment.GetEnvironmentVariable("DB_HOST");

// Avec valeur par défaut grâce à ?? (null-coalescing)
string host = Environment.GetEnvironmentVariable("DB_HOST") ?? "localhost";
int port = int.Parse(Environment.GetEnvironmentVariable("DB_PORT") ?? "3306");

// Vérifier qu'une variable critique est définie
string? mdp = Environment.GetEnvironmentVariable("DB_PASSWORD");
if (string.IsNullOrEmpty(mdp))
{
Console.Error.WriteLine("ERREUR : DB_PASSWORD non définie !");
Environment.Exit(1);
}

appsettings.json — configuration .NET standard

Le fichier appsettings.json est l'approche standard pour la configuration non sensible :

{
"Database": {
"Host": "localhost",
"Port": 3306,
"Name": "ma_base"
},
"AppName": "MonApplication"
}
Ne jamais mettre de mots de passe dans appsettings.json

appsettings.json est committé dans git. Ne l'utilisez que pour des valeurs non sensibles (host, port, nom de base). Les mots de passe restent dans des variables d'environnement ou dans appsettings.Development.json (exclu du git via .gitignore).

Paquet DotNetEnv — fichier .env

Le paquet DotNetEnv permet de charger des variables depuis un fichier .env (pratique en développement) :

dotnet add package DotNetEnv
// Charger le fichier .env au démarrage
DotNetEnv.Env.Load();

string host = Environment.GetEnvironmentVariable("DB_HOST") ?? "localhost";

Fichier .envne jamais committer — ajoutez-le au .gitignore) :

DB_HOST=localhost
DB_PORT=3306
DB_NAME=mabase
DB_PASSWORD=secret
Le fichier .env dans .gitignore

Ajoutez toujours .env à votre .gitignore. Ce fichier contient des secrets et ne doit jamais être poussé sur le dépôt distant. Committez à la place un fichier .env.example avec des valeurs fictives pour documenter les variables attendues.

L'opérateur ?? — valeur par défaut

string? valeur = null;
string resultat = valeur ?? "défaut"; // "défaut" car valeur est null

// Enchaînable
string config = Environment.GetEnvironmentVariable("HOST")
?? Environment.GetEnvironmentVariable("HOSTNAME")
?? "localhost";

Exemple pratique

// Lecture de la configuration depuis l'environnement
string dbHost = Environment.GetEnvironmentVariable("DB_HOST") ?? "localhost";
string dbPort = Environment.GetEnvironmentVariable("DB_PORT") ?? "3306";
string dbName = Environment.GetEnvironmentVariable("DB_NAME") ?? "mabase";
string? dbPass = Environment.GetEnvironmentVariable("DB_PASSWORD");
string appEnv = Environment.GetEnvironmentVariable("APP_ENV") ?? "development";

// Vérification de la variable critique
if (string.IsNullOrEmpty(dbPass))
{
Console.Error.WriteLine("⚠ DB_PASSWORD non définie. Utilisation de la valeur par défaut (DANGEREUX en production !)");
dbPass = "changeme";
}

// Masquage du mot de passe pour l'affichage
string masque = dbPass.Length > 2
? new string('*', dbPass.Length - 2) + dbPass[^2..]
: "****";

Console.WriteLine("=== Configuration de l'application ===");
Console.WriteLine($"Environnement : {appEnv.ToUpper()}");
Console.WriteLine($"Base de données :");
Console.WriteLine($" Host : {dbHost}");
Console.WriteLine($" Port : {dbPort}");
Console.WriteLine($" Nom : {dbName}");
Console.WriteLine($" Password : {masque}");

// Construire la chaîne de connexion
string connexion = $"Server={dbHost};Port={dbPort};Database={dbName};Uid=root;Pwd={dbPass};";
Console.WriteLine($"\nChaîne de connexion :");
Console.WriteLine($" {connexion.Replace(dbPass, masque)}");

Test de mémorisation/compréhension


Quelle méthode C# lit une variable d'environnement ?


Quelle est la commande PowerShell (Windows) pour définir une variable d'environnement temporaire ?


À quoi sert l'opérateur `??` dans `GetEnvironmentVariable("HOST") ?? "localhost"` ?


Pourquoi ne faut-il pas mettre de mots de passe dans `appsettings.json` ?


Quel fichier doit TOUJOURS être ajouté au `.gitignore` quand on utilise DotNetEnv ?


TP pour réfléchir et résoudre des problèmes

Vous allez créer un programme qui lit sa configuration depuis les variables d'environnement.

Étape 1 — Définir les variables (Windows et Linux)

Définissez les variables d'environnement pour le projet.


Bonne pratique - Variables temporaires pour le développement

Les variables définies avec $env: (PowerShell) ou export (Bash) sont temporaires : elles disparaissent à la fermeture du terminal. Pour le développement, utilisez un fichier .env avec le paquet DotNetEnv. Pour la production (serveur, Docker), définissez les variables de façon permanente dans le système ou le conteneur.

Étape 2 — Lire la configuration en C#

Lisez les variables et fournissez des valeurs par défaut.


Bonne pratique - Toujours fournir une valeur par défaut

Utilisez ?? "valeur_par_defaut" pour les variables optionnelles. Pour les variables obligatoires (mot de passe, clé API), vérifiez qu'elles sont définies et quittez proprement si ce n'est pas le cas, plutôt que de continuer avec une valeur nulle.

Étape 3 — Masquer le secret et sauvegarder la config

Masquez la valeur sensible et sauvegardez la configuration dans un fichier.


Bonne pratique - Ne jamais afficher un secret en clair

Masquez toujours les valeurs sensibles avant de les afficher dans les logs ou la console. L'opérateur [^2..] (range depuis la fin) extrait les 2 derniers caractères, suffisant pour confirmer que la variable est définie sans révéler sa valeur.

📌 Une solution