Audit des URL codées en dur : corriger les liens de staging et les callbacks
Audit des URL codées en dur pour repérer les liens de staging et callbacks vers localhost, puis les déplacer en configuration d'environnement avec des valeurs sûres pour la production.

Que se passe-t-il quand les URLs et callbacks sont codés en dur
Une URL codée en dur est une adresse web écrite directement dans votre code, comme https://staging.example.com ou http://localhost:3000, au lieu d'être lue depuis la configuration selon l'environnement. Ça paraît plus rapide lors d'un prototype, mais ça attache votre appli à un seul endroit.
Une URL de callback est l'endroit où un autre service renvoie les utilisateurs ou les données vers vous. Exemples courants : les redirections OAuth (Google renvoie l'utilisateur après la connexion) et les webhooks (Stripe, GitHub, ou un outil de formulaires envoie des événements à votre serveur). Si ce callback pointe vers le mauvais endroit, le service externe fait son travail, mais votre appli ne reçoit jamais le résultat.
Quand des liens de staging ou des callbacks vers localhost se retrouvent en production, les vrais utilisateurs tombent dans des impasses. localhost n'existe que sur la machine du développeur, donc un utilisateur en production ne peut pas y accéder. Les domaines de staging utilisent souvent des cookies, des secrets et des origines autorisées différents. Même si la page charge, la session ou la requête peut échouer.
Cela se manifeste en général par :
- Une connexion qui fonctionne chez le fournisseur, puis un retour sur une page vide ou une erreur
- Des webhooks qui échouent silencieusement ou qui réessaient sans cesse car le endpoint est erroné
- Des liens de réinitialisation de mot de passe ou de vérification d'email envoyant vers le staging
- Des boucles de redirection causées par des domaines mélangés (l'app pointe vers staging, l'API vers prod)
- Des erreurs CORS parce que l'origine du frontend ne correspond pas à ce que l'API attend
Ces problèmes s'assemblent souvent autour de l'auth, des paiements et des flux d'email parce qu'ils dépendent d'URLs exactes et préenregistrées.
C'est particulièrement courant dans les prototypes générés par IA et les builds précipités. Les outils génèrent souvent du code « happy path » avec des domaines placeholders, des snippets copiés/collés et des valeurs par défaut comme localhost. Si personne ne passe en production pour déplacer ces valeurs dans la config d'environnement, l'app continue d'envoyer les mauvaises URLs.
Où se cachent généralement les liens de staging et les callbacks localhost
La plupart des équipes vérifient un fichier pour une URL de base, puis sont surprises quand les utilisateurs touchent encore au staging. Supposons que la mauvaise URL peut se cacher sur plusieurs couches : le bundle frontend, les utilitaires backend et les dashboards tiers.
Sur le frontend, cherchez les bases d'API, les URI de redirection OAuth et les chemins d'assets. Dans le code généré par des outils comme Lovable, Bolt, v0, Cursor ou Replit, il est courant de trouver http://localhost:3000 intégré dans un appel fetch, un helper d'auth ou une variable build-time. Un autre problème fréquent est qu'un .env.example copié devienne accidentellement le vrai .env lors du déploiement.
Sur le backend, surveillez les URLs intégrées dans des utilitaires utiles : callbacks de webhook, liens de réinitialisation de mot de passe, liens de connexion magique et emails d'invitation. Ils concatènent souvent un hostname dans le code, donc même si vous corrigez une valeur de config, les liens d'email peuvent toujours pointer vers le staging. Les réglages CORS sont un autre piège : une seule origine http://localhost:5173 oubliée peut casser la connexion en production (ou autoriser accidentellement une origine non voulue).
Les derniers liens de staging restants se trouvent généralement dans l'un de ces endroits :
- Constantes frontend et clients d'API
- Helpers de redirection d'auth
- Configuration serveur pour CORS, webhooks et génération de liens d'email
- Configuration de déploiement (variables CI, Docker, scripts)
- Dashboards tiers (fournisseurs OAuth, paiements, analytics)
Une panne réelle courante : Google OAuth est correctement configuré chez le fournisseur, mais l'app envoie toujours les utilisateurs vers un callback localhost parce que le code contient un fallback codé en dur. Tout semble correct jusqu'à ce qu'un utilisateur production essaie de se connecter et soit redirigé vers sa propre machine.
Étape par étape : réaliser un audit des URLs codées en dur et des callbacks
D'abord, listez les environnements que votre appli utilise réellement. La plupart des équipes ont besoin de trois : local (votre laptop), staging (un serveur de test) et production (vrais utilisateurs). Si vous avez aussi des déploiements preview ou des environnements démo client, incluez-les. Ce sont souvent des environnements supplémentaires où les mauvaises URLs réapparaissent.
Ensuite, faites une recherche ciblée pour les valeurs qui devraient varier par environnement mais qui sont figées dans le code.
- Cherchez :
localhost,127.0.0.1,0.0.0.0,staging,dev.,ngrok,vercel.app,railway.app - Cherchez les URLs complètes :
http://ethttps:// - Cherchez des clés de config :
BASE_URL,FRONTEND_URL,API_URL,CALLBACK_URL,REDIRECT_URI,WEBHOOK_URL - Vérifiez les templates : textes d'email, liens de réinitialisation, invitations et boutons "ouvrir dans le navigateur"
- Vérifiez aussi les config mobile et desktop (les deep links et schémas personnalisés peuvent être codés en dur)
Ne vous arrêtez pas au repo. Certaines des configurations les plus douloureuses vivent dans les dashboards : fournisseurs OAuth, webhooks de paiement, fournisseurs d'email et services d'auth. Si la connexion fonctionne en local mais échoue en production, c'est souvent un décalage entre ce que le fournisseur attend et ce que votre appli envoie.
Au fur et à mesure que vous trouvez des problèmes, notez-les dans un petit tableau (un doc de notes suffit). Capturez :
- Où vous l'avez trouvé (fichier, service ou dashboard)
- La valeur exacte
- Ce que ça casse
- Ce que ça devrait être en local, staging et production
Si le projet a été généré rapidement depuis des templates, attendez-vous à des doublons. Il est courant de trouver la même URL codée en dur dans le code UI et le code serveur. Obtenir une liste complète en premier empêche le cycle « je l'ai corrigé une fois, ça casse ailleurs ».
Déplacer les URLs dans la configuration d'environnement (sans casser l'app)
Les URLs codées en dur échouent silencieusement. L'app marche sur votre machine, puis un déploiement envoie les utilisateurs vers le staging, ou la redirection renvoie vers localhost et personne ne peut se connecter.
La correction est simple : mettez chaque URL qui peut changer dans la configuration d'environnement, puis lisez-la depuis un seul endroit.
Commencez par grouper les URLs par fonction, pas par l'endroit où vous les avez trouvées. La plupart des applications ont trois bacs :
- Adresse publique de l'app (ce que voient les utilisateurs)
- Adresse de base de l'API (ce que le frontend appelle)
- Adresses de callback/redirection (où les services tiers rappellent)
Utilisez des variables d'environnement pour tout ce qui diffère entre local, staging et production. Gardez des noms cohérents pour qu'ils soient faciles à repérer :
- APP_URL
- API_URL
- OAUTH_REDIRECT_URL
- WEBHOOK_BASE_URL
- ASSET_URL (si vous avez un CDN/stockage)
Puis centralisez l'accès via un module de config ou un fichier de settings. La règle : le reste du code ne lit jamais process.env directement. Ça réduit la dérive et empêche les valeurs par défaut copiées/collées de se répandre.
// config.js
const required = (name) => {
const v = process.env[name];
if (!v) throw new Error(`${name} is missing`);
return v;
};
export const config = {
appUrl: required('APP_URL'),
apiUrl: required('API_URL'),
oauthRedirectUrl: required('OAUTH_REDIRECT_URL'),
};
Conservez des valeurs par défaut sûres uniquement pour le développement local, et faites en sorte que la production échoue rapidement. Par exemple, par défaut APP_URL peut valoir http://localhost:3000 en dev, mais en production il vaut mieux crasher au démarrage plutôt que d'envoyer de vrais utilisateurs vers localhost.
Pour éviter les régressions, changez un chemin à la fois. Remplacez les chaînes codées par les valeurs de config, déployez en staging et confirmez que le flux fonctionne toujours (surtout la connexion et la réinitialisation de mot de passe).
Valeurs par défaut sûres et garde‑fous à ajouter
Après avoir déplacé les valeurs en config, le risque suivant est les fallbacks qui pointent vers le mauvais endroit.
En dev local, les valeurs par défaut doivent être sûres et évidentes. En production, l'app doit échouer rapidement si une URL requise est manquante ou manifestement incorrecte.
Garde‑fous efficaces dans la plupart des apps :
- Valider la config au démarrage : clés requises présentes, URLs parsables, schémas attendus (https en prod)
- Bloquer localhost et domaines de staging dans toute build de production
- Maintenir une whitelist de domaines pour les callbacks et redirects
- Garder les erreurs claires mais non sensibles : indiquer quelle clé est invalide et pourquoi, sans afficher de secrets
- Rendre les mauvaises config évidentes dans les logs et le monitoring : un message court pointant le réglage manquant ou invalide
Un exemple simple : si OAUTH_REDIRECT_URL est vide, un default imprudent peut devenir http://localhost:3000/callback même sur un serveur. Votre garde‑fou devrait détecter le couple "prod + localhost" et crasher avec un message comme « Invalid OAUTH_REDIRECT_URL for production: localhost not allowed. »
Zones à haut risque : auth, webhooks, CORS et liens d'email
Ce sont les endroits où une mauvaise URL casse vite l'expérience utilisateur, et les échecs peuvent sembler aléatoires : boucles de connexion, événements webhook manquants, erreurs CORS intermittentes ou emails qui mènent au mauvais endroit.
Auth (OAuth, SSO), cookies et sessions
Les redirect URIs OAuth/SSO doivent correspondre exactement : schéma (http vs https), domaine et chemin. Un seul http://localhost ou un domaine de staging résiduel peut empêcher tout le monde de se connecter.
Même si la redirection semble correcte, les cookies et sessions peuvent échouer :
- Le domaine du cookie ne correspond pas
- Le flag
securemanque en production - Les réglages
sameSitene conviennent pas au flux (notamment entre domaines)
Un symptôme typique est « je me suis connecté, puis j'ai l'air déconnecté instantanément ».
Webhooks, CORS et liens d'email
Les webhooks nécessitent des callbacks spécifiques à l'environnement et des secrets de signature. Une erreur fréquente : pointer les webhooks de production vers le staging, puis se demander pourquoi les commandes, paiements ou jobs de synchronisation n'arrivent jamais. Une autre erreur est d'utiliser la bonne URL mais le mauvais secret de signature, ce qui rend chaque requête invalide.
CORS devrait être une allowlist, pas un wildcard. Origines locales, staging et production doivent être séparées, et l'API ne doit accepter que celles attendues.
Les liens d'email (réinitialisation, invitations, magic links) doivent utiliser l'URL publique de votre app. S'ils pointent vers localhost ou le staging, les utilisateurs cliquent et tombent sur une page morte.
Un passage rapide d'audit pour ces zones :
- Cherchez
localhost, domaines de staging et anciens domaines produits - Vérifiez les redirect URIs OAuth et les paramètres de cookie par environnement
- Vérifiez que les URLs de webhook et les secrets de signature sont correctement appariés
- Confirmez que les origines CORS correspondent à vos frontends réels
- Envoyez un email de reset test et cliquez sur le lien depuis une vraie boite
Comment tester après le changement (rapide mais fiable)
Après avoir déplacé les URLs et callbacks en config, les tests consistent surtout à s'assurer que chaque environnement pointe vers lui‑même et nulle part ailleurs.
Écrivez une petite matrice d'environnement : une ligne par environnement (local, staging, production) et quelques colonnes pour les valeurs qui comptent (URL de base de l'app, URL API, callback OAuth, URL de réception des webhooks, domaine des liens d'email). L'objectif n'est pas une documentation parfaite, mais d'arrêter les suppositions.
Puis effectuez un smoke test qui touche les flows les plus susceptibles de casser quand un callback est mauvais :
- Connexion et déconnexion (y compris « Continuer avec Google/GitHub »)
- Inscription et réinitialisation de mot de passe (cliquer le lien d'email de bout en bout)
- Redirects de succès/annulation de paiement (si vous utilisez un fournisseur de paiement)
- Un webhook entrant (déclenchez un événement de test depuis le fournisseur)
- Tout magic link ou flow d'invitation dont vos utilisateurs dépendent
Pendant ces tests, surveillez les redirections inattendues. Une panne fréquente : « la connexion fonctionne, puis on atterrit sur le staging » parce qu'un callback reste pointé vers un ancien domaine.
Ouvrez le panneau Réseau du navigateur et scannez les domaines des requêtes. Cherchez n'importe quoi d'inattendu : localhost, un sous‑domaine de staging, une IP brute ou une URL de preview oubliée. Quand vous en repérez une, notez l'action qui l'a déclenchée et retracez-la jusqu'à la valeur de config.
Enfin, confirmez que les dashboards tiers correspondent à ce que vous avez déployé. Les paramètres de votre app OAuth doivent lister le callback de production quand vous testez la production, et votre fournisseur de webhooks doit envoyer les événements vers le endpoint de production.
Erreurs courantes qui font revenir le problème
La plupart des équipes corrigent une URL évidente, déploient et passent à autre chose. Une semaine plus tard, quelqu'un trouve un autre lien de staging caché dans un fichier différent, ou la connexion casse parce qu'un callback pointe encore vers localhost.
Coupables récurrents :
- Hotfixs temporaires codant en dur une redirection ou un webhook « juste pour maintenant »
- Mélange de valeurs staging et production dans le même fichier d'environnement
- Dérive de noms entre services (
PUBLIC_APP_URLd'un côté,APP_URLde l'autre) - Commits accidentels de fichiers
.envlocaux ou de valeurs de config copiées dans le code
Quelques règles qui évitent la plupart des régressions :
- Utilisez un nom de variable cohérent par paramètre dans l'app web, l'API et les workers
- Séparez staging et production dans des configs de déploiement distinctes
- Considérez localhost et les domaines de staging comme invalides dans les builds de production
- Incluez les callbacks mobiles et deep links dans le même audit si vous les publiez
Checklist rapide avant de livrer
Avant de déployer, faites une passe finale centrée sur les URLs et callbacks.
- Construisez votre bundle de production et recherchez-y (et dans vos logs) des chaînes comme
localhost,127.0.0.1,staging,ngrokou de vieux domaines de preview - Confirmez que chaque URL externe (API base URL, OAuth redirect URI, webhook target, origine frontend, host des liens d'email) provient bien de la configuration d'environnement
- Assurez‑vous que l'app échoue rapidement quand une URL requise est manquante
- Testez le parcours utilisateur complet de bout en bout dans l'environnement réellement déployé
- Revérifiez que les dashboards tiers correspondent à l'environnement déployé (même domaine, mêmes chemins de callback, même protocole)
Un conseil pratique : ouvrez les réglages de votre fournisseur d'auth et comparez les redirect URLs autorisées avec ce que votre app affiche au démarrage. S'ils ne correspondent pas exactement, la connexion peut échouer avec des erreurs déroutantes de type « callback mismatch ».
Exemple : corriger un callback OAuth vers localhost qui casse la connexion
Un pattern courant ressemble à ceci : la connexion marche sur votre laptop, mais en production les utilisateurs sont renvoyés vers une page vide ou une erreur comme « redirect_uri mismatch ». Votre app est correcte, mais le fournisseur OAuth envoie les utilisateurs au mauvais endroit.
Pendant l'audit, cherchez des termes comme localhost, 127.0.0.1, votre domaine de staging et /callback. Un coupable fréquent est un fichier de config d'auth copié depuis les tests locaux et jamais mis à jour.
Voici à quoi ressemble souvent ce bug en code :
// auth.config.js (problem)
export const oauthRedirectUrl = "http://localhost:3000/auth/callback";
La correction comporte deux volets. D'abord, déplacez la valeur dans la config d'environnement avec un fallback sûr pour le dev local :
// auth.config.js (fixed)
const DEFAULT_REDIRECT = "http://localhost:3000/auth/callback";
export const oauthRedirectUrl = process.env.OAUTH_REDIRECT_URL || DEFAULT_REDIRECT;
Ensuite, mettez à jour les paramètres du fournisseur OAuth pour autoriser le callback de production, par exemple https://yourdomain.com/auth/callback (et seulement les domaines que vous utilisez réellement). Si vous avez aussi un staging, ajoutez-y un callback distinct, mais gardez‑les séparés.
Ajoutez un simple garde‑fou au démarrage pour empêcher une prod de booter avec des settings localhost :
if (process.env.NODE_ENV === "production" && oauthRedirectUrl.includes("localhost")) {
throw new Error("OAUTH_REDIRECT_URL is still localhost in production");
}
Puis retestez le flux complet : cliquez sur « Sign in », complétez l'écran de consentement du fournisseur, et vérifiez que vous arrivez bien sur le domaine correct et que vous restez connecté après un refresh.
Étapes suivantes si votre app a été construite par IA et continue d'expédier de mauvaises URLs
Si l'app a été générée avec des outils comme Lovable, Bolt, v0, Cursor ou Replit, les mauvaises URLs sont souvent le symptôme de valeurs par défaut dispersées et de garde‑fous manquants. Parfois la réparation est rapide. D'autres fois, c'est le signe que la base doit être nettoyée.
C'est généralement un correctif rapide quand vous pouvez centraliser les valeurs dans un module de config, ajouter une validation au démarrage et tout fonctionne de la même façon en local, staging et production.
C'est plutôt un refactor quand la logique de construction d'URL est dupliquée dans de nombreux fichiers, que différentes fonctionnalités fabriquent leurs propres callbacks, ou que les changements continuent de casser l'auth et les webhooks.
Signes qu'il faut plus qu'un audit rapide :
- Plusieurs manières de construire la même URL dans l'app
- Callbacks d'auth différents entre frontend et backend
- Secrets ou clés API commis à côté de constantes d'URL
- Allowlists CORS et webhooks définies en code plutôt qu'en config
- Corriger un endroit provoque la casse d'autres environnements
Si vous voulez une deuxième paire d'yeux rapide sur une base héritée générée par IA, FixMyMess (fixmymess.ai) se concentre sur le diagnostic et la réparation de problèmes comme les callbacks codés en dur, les flux d'auth cassés, les secrets exposés et les valeurs par défaut dangereuses pour que l'app se comporte correctement en production.
Questions Fréquentes
Pourquoi les URL codées en dur posent-elles un si gros problème en production ?
Parce qu'elles verrouillent votre app sur un seul environnement. Quand vous déployez, les utilisateurs peuvent être redirigés vers le staging ou même localhost, qu'ils ne peuvent pas atteindre — du coup la connexion, les webhooks et les liens d'email cassent de façon apparemment aléatoire.
Quel est le moyen le plus rapide pour repérer une redirect OAuth cassée ?
Les fournisseurs OAuth exigent une correspondance exacte de la redirect URL. Si votre app envoie http://localhost... ou un domaine de staging comme redirect, le fournisseur peut le rejeter ou renvoyer les utilisateurs vers une page morte où la session ne se termine jamais.
Pourquoi `localhost` dans un callback casse-t-il pour de vrais utilisateurs ?
localhost pointe vers l'ordinateur de l'utilisateur, pas vers votre serveur. En production, cela signifie que callbacks, appels API et liens peuvent aboutir nulle part, même si tout fonctionnait lors des tests locaux.
Par où dois‑je commencer à chercher des URL codées en dur ?
Commencez par chercher localhost, 127.0.0.1, staging, d'anciens domaines et les chaînes complètes http:// ou https:// dans tout le dépôt. Vérifiez aussi les templates d'email et tout code qui construit des liens en concaténant un hostname.
Le mauvais callback peut-il être dans un dashboard fournisseur même si mon code est correct ?
Oui — les dashboards tiers. Les apps OAuth, les fournisseurs de paiement, les expéditeurs de webhooks et les services d'email gardent souvent des callbacks en dehors de votre code, donc vous pouvez « corriger » le dépôt et continuer à recevoir des événements vers le mauvais endroit.
Quelle est une manière propre de déplacer les URL en config d'environnement ?
Placez les URL variables par environnement dans des variables d'environnement comme APP_URL, API_URL et OAUTH_REDIRECT_URL, puis lisez-les via un module de config unique. Évitez de parsemer des lectures de process.env partout pour éviter les sources conflictuelles.
Quels garde‑fous empêchent que des URLs de staging ou localhost n'arrivent en production ?
Autorisez des valeurs sûres seulement en développement local, et faites échouer rapidement en production. Si une URL requise est absente ou pointe vers localhost ou le staging alors que NODE_ENV vaut production, faites crasher le démarrage avec une erreur claire pour éviter d'envoyer des flows cassés en silence.
Quels domaines se cassent le plus souvent quand les URL sont erronées ?
Auth, webhooks, CORS et liens d'email. Ces chemins dépendent d'un domaine et d'un protocole exacts — de petites différences provoquent boucles de connexion, événements manquants, requêtes bloquées ou emails renvoyant vers le mauvais site.
Comment tester rapidement après avoir corrigé les URL et callbacks ?
Faites un test end‑to‑end par environnement : login/logout, réinitialisation de mot de passe depuis une vraie boite mail, un événement de webhook de test, et tout redirect de paiement si vous en avez. Pendant les tests, surveillez le réseau du navigateur pour repérer des domaines inattendus comme staging, des previews ou des IP brutes.
Quand s'agit‑il d'une correction rapide vs d'un signe que la base nécessite un nettoyage profond ?
Si les URL sont dispersées dans de nombreux fichiers, si l'auth et les webhooks diffèrent entre frontend et backend, ou si chaque correction casse un autre environnement, ce n'est généralement pas une simple ligne à modifier. Dans ce cas, une remise en ordre plus profonde est nécessaire. FixMyMess peut auditer une base générée par IA, centraliser la config, réparer les flux d'auth et de webhooks, et rétablir un comportement correct en production rapidement.