Protéger les accès et les secrets
Objectif : Configurer une connexion à la base utilisable côté serveur sans exposer de clé au navigateur.
Une connexion à la base du catalogue peut nécessiter une URL, un identifiant ou une clé privée. Si l’un de ces secrets atteint le navigateur, une personne peut le récupérer et accéder aux données sans passer par vos pages.
Vous allez définir une frontière claire : les pages du catalogue utilisent la configuration côté serveur, tandis que le navigateur ne reçoit que les données nécessaires à l’affichage. Les composants serveur et le transfert de données sont déjà présentés dans les leçons précédentes ; ici, vous protégez les informations qui rendent l’accès possible.
Séparer les réglages publics et secrets
Next.js lit les variables d’environnement dans `process.env`. Une variable sans préfixe `NEXT_PUBLIC_` reste destinée au code serveur. À l’inverse, une variable portant ce préfixe est conçue pour être intégrée au code envoyé au navigateur : ne l’utilisez jamais pour une clé de base de données, un mot de passe ou un jeton privé.
DATABASE_URL=postgresql://utilisateur:mot-de-passe@localhost:5432/randonnees
NEXT_PUBLIC_SITE_URL=https://catalogue.exampleLa ligne `DATABASE_URL` représente un secret : gardez-la dans la configuration locale ignorée par le contrôle de version ou dans les paramètres d’environnement de votre hébergeur. Le dépôt du projet ne doit contenir ni sa valeur réelle ni une copie de fichier contenant des identifiants. L’adresse publique du site n’est pas un secret ; le préfixe `NEXT_PUBLIC_` signale qu’elle peut être utilisée par du code client.
Marquer le code sensible comme réservé au serveur
Le paquet `server-only` permet de signaler qu’un module ne doit être importé que depuis du code serveur. Si un composant client tente de l’importer, Next.js produit une erreur à la compilation plutôt que de laisser cette dépendance sensible entrer dans le bundle navigateur. Dans le projet fil rouge, l’accès à la base restera côté serveur, conformément au contrat ; vous n’ajoutez donc pas de nouveau fichier ni de composant client pour cette configuration.
import 'server-only';
export default async function CataloguePage() {
const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) {
throw new Error('La variable DATABASE_URL doit être configurée.');
}
return <h1 className="rando-titre">Randonnées à découvrir</h1>;
}Cet exemple montre un contrôle de configuration dans une page serveur existante, sans afficher l’URL ni la transmettre en propriété. En l’intégrant à la page du catalogue, conservez le rendu et les éléments déjà présents : le retour JSX ci-dessus est seulement une illustration du contrôle, pas un remplacement de la page complète. La création de la fonction d’accès aux données et la connexion effective à la base seront traitées dans les leçons suivantes.
La vérification évite de poursuivre avec une configuration absente et fournit une erreur explicite dans les journaux serveur. Elle ne révèle pas la valeur de la variable. Vérifiez également que les messages d’erreur produits par vos outils ne recopient pas l’URL complète, car celle-ci peut contenir des identifiants.
Vérifier la frontière de sécurité
Avant de publier, contrôlez les noms et les usages des variables : une clé de base de données ne doit apparaître que dans la configuration serveur et dans le code serveur qui en a besoin. Ne l’insérez ni dans une URL de navigation, ni dans un attribut HTML, ni dans des données préparées pour le navigateur. Les composants client éventuels doivent recevoir des valeurs d’affichage, pas des accès ou des secrets.
À retenir
- Gardez les identifiants et clés de base dans des variables d’environnement sans préfixe `NEXT_PUBLIC_`.
- Utilisez `server-only` pour protéger les modules qui manipulent des secrets.
- Vérifiez la présence d’une configuration côté serveur sans afficher sa valeur.
- Ne transmettez au navigateur que les données nécessaires à l’interface, jamais les accès à la base.
Dans la prochaine leçon, vous mettrez en place la couche serveur qui interroge les données du catalogue.