La petite erreur entre frontend, backend et Azure qui casse la production

Un host ou un scheme mal interprété peut suffire. Frontend, backend et Azure travaillent alors selon des versions différentes de la même réalité.

L’article complet est disponible ci-dessous. Activez JavaScript pour les quiz et les simulations.

La petite erreur entre frontend, backend et Azure qui casse la production

Dans les projets modernes, on croit facilement que le plus grand risque réside dans les grandes décisions d’architecture. L’équipe parle de modèles, cloud, sécurité, évolutivité, responsabilités et contrats entre services. Tout cela compte. Pourtant, la production échoue souvent ailleurs. Elle échoue à cause de petites erreurs qui semblaient anecdotiques.

Même des équipes expérimentées supposent alors que si le frontend fonctionne en local, que le backend répond et que le déploiement passe au vert, le système est prêt. Ce n’est pas suffisant. Entre « fonctionne » et « fonctionne correctement en production », l’écart est considérable.

Un cas particulièrement trompeur apparaît lorsque frontend, backend et infrastructure Azure travaillent selon des versions différentes de la même réalité. Chaque couche interprète à sa façon la requête, le host, le scheme, l’origin, les cookies et le trajet du trafic. Le système semble alors instable, incohérent et risqué à maintenir.

Pourquoi ce problème est dangereux

Ces pannes produisent rarement un message unique et clair. Elles se dispersent en symptômes :

  • connexion intermittente,
  • session perdue après actualisation,
  • 401 côté frontend malgré une connexion précédente,
  • redirection d’authentification vers une mauvaise adresse,
  • cookies visibles mais absents des requêtes suivantes,
  • CORS correct sur un parcours et défaillant sur un autre,
  • fonctionnement local normal mais retour imprévisible du problème dans Azure.

Ce type de défaut détruit la confiance dans le système. L’utilisateur ne voit ni host mal transmis ni scheme mal interprété derrière le reverse proxy. Il voit simplement que le système est instable.

Le problème dans un projet réel

Prenons une configuration courante :

  • Angular pour l’interface d’administration,
  • ASP.NET Core pour l’API backend,
  • Azure App Service pour l’hébergement,
  • Azure Front Door ou Application Gateway comme couche d’entrée,
  • un domaine propre,
  • une connexion par cookies, session ou callback d’authentification.

Le diagramme semble mature. En local, tout va bien. Le staging ne montre pas de gros défauts. C’est là que survient le piège : l’équipe considère l’architecture valide parce que les tests élémentaires passent.

La production montre vite que cela ne suffit pas.

Une petite erreur suffit :

  • le backend interprète mal X-Forwarded-Proto,
  • l’application voit une requête en httpalors que l’utilisateur est arrivé en https,
  • host public et host interne sont confondus,
  • le frontend construit l’adresse API depuis la mauvaise source,
  • les cookies suivent une politique incompatible avec le parcours réel,
  • le callback est généré avec le mauvais domaine.

Séparément, ces détails paraissent anodins. Ensemble, ils créent une architecture fissurée derrière un fonctionnement apparent.

L’erreur de l’équipe : traiter les symptômes plutôt que la cause

La réaction est souvent la même : exception supplémentaire dans l’intercepteur frontend, nouveau if-adans le backend, règle ajoutée dans l’infrastructure, URL forcée manuellement et politique de sécurité temporairement assouplie pour débloquer la release.

C’est un moment dangereux.

L’équipe a l’impression d’avoir corrigé quelque chose, mais ne traite que les symptômes. La cause reste présente. Le système ne partage toujours pas une définition commune de la requête. Le problème reviendra donc sous une autre forme au prochain déploiement, parcours ou changement de domaine.

L’architecture devient rapidement un assemblage de contournements. Elle fonctionne à peu près, mais personne ne la touche sereinement.

Les tâches concrètes qui révèlent les fissures

Les problèmes apparaissent mieux dans les opérations métier et techniques que sur les diagrammes.

1. Connexion à l’administration

Identifiant, mot de passe, authentification, puis tableau de bord : cela devrait être simple. Pourtant, c’est souvent ici que le système révèle sa mauvaise compréhension du domaine public et de HTTPS.

Symptômes :

  • cookie enregistré mais absent de la requête suivante,
  • frontend connecté alors que le backend renvoie 401,
  • session perdue après actualisation du panneau,
  • redirection vers une mauvaise adresse ou un mauvais host.

Ce n’est pas un simple désagrément : la confiance dans le produit est directement touchée.

2. Publication dans l’administration

L’éditeur utilise souvent une route API, des politiques d’autorisation et des requêtes différentes de la partie publique. Les incohérences de cookies, hosts et CORS y apparaissent.

Symptômes :

  • Le brouillon s’enregistre en local mais pas en production,
  • la publication échoue malgré des données correctes,
  • la requête est envoyée correctement mais le backend ne retrouve pas l’utilisateur dans la session,
  • certains endpoints fonctionnent, d’autres semblent aléatoires.

Cela signale généralement un défaut d’interprétation des requêtes et de l’autorisation entre couches, pas du formulaire lui-même.

3. Callback d’un prestataire externe

Avec OAuth, paiements et autres intégrations, le défaut devient encore plus évident. Un callback construit sur un domaine ou un scheme erroné désorganise le parcours entier.

Symptômes :

  • Le retour du service externe arrive à la mauvaise adresse,
  • la requête revient en HTTP au lieu de HTTPS,
  • le fournisseur refuse le callback,
  • le parcours fonctionne dans un environnement mais pas l’autre.

Il faut une interprétation commune du trafic ; compter sur la chance n’est pas une solution pour les intégrations.

4. Liens profonds et actualisation

Dans une SPA, l’accès direct à une sous-page ou son actualisation révèle souvent le défaut. Routage, autorisation et backend ne partagent plus le même contexte. Le frontend restaure l’état, le backend voit une session absente ou une origine incorrecte, et l’utilisateur subit un comportement confus. Le piège est que les clics de test simples passent, alors que l’usage normal échoue.

Un problème réel que nous avons récemment résolu

Un cas concret dans cette configuration survient lorsque le frontend construit les adresses API depuis l’origin courant, tandis que le backend configure trop tard la gestion de ForwardedHeaders. Cela peut fonctionner localement, puis se désorganiser derrière un proxy et le domaine de production.

Le mauvais modèle côté frontend
const apiUrl = `${window.location.origin}/api`;

Pratique en local, il devient problématique lorsque :

  • l’administration utilise un domaine,
  • l’API en utilise un autre,
  • le trafic traverse un proxy,
  • le host public diffère du host interne.
Une version plus stable
export interface AppEnvironment {
  production: boolean;
  apiBaseUrl: string;
}

export const environment: AppEnvironment = {
  production: true,
  apiBaseUrl: 'https://api.twojadomena.pl'
};

@Injectable({ providedIn: 'root' })
export class ApiConfigService {
  readonly baseUrl = environment.apiBaseUrl.replace(/\/+$/, '');
}
Un intercepteur qui normalise l’adresse au lieu de la deviner
import { HttpInterceptorFn } from '@angular/common/http';
import { inject } from '@angular/core';

export const apiBaseUrlInterceptor: HttpInterceptorFn = (req, next) => {
  if (/^https?:\/\//i.test(req.url)) {
    return next(req);
  }

  const config = inject(ApiConfigService);
  const normalizedUrl = `${config.baseUrl}/${req.url.replace(/^\/+/, '')}`;

  return next(
    req.clone({
      url: normalizedUrl,
      withCredentials: true
    })
  );
};

La seconde partie du défaut était côté backend. Si la gestion de UseForwardedHeaders() arrive trop tard, la suite du pipeline travaille déjà sur une représentation erronée de la requête.

La bonne direction dans ASP.NET Core
using Microsoft.AspNetCore.HttpOverrides;

builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders =
        ForwardedHeaders.XForwardedFor |
        ForwardedHeaders.XForwardedProto |
        ForwardedHeaders.XForwardedHost;

    options.KnownNetworks.Clear();
    options.KnownProxies.Clear();
});

var app = builder.Build();

app.UseForwardedHeaders();

app.UseCors("AdminCors");
app.UseAuthentication();
app.UseAuthorization();

Voilà un petit défaut capable de casser :

  • la connexion,
  • les cookies,
  • les redirections,
  • les callbacks,
  • la génération des liens,
  • la cohérence frontend-backend.

Ce qu’il faut réellement réussir

La correction ne consiste pas à ajouter des exceptions. Elle consiste à établir une vérité commune pour tout le parcours.

  • Le frontend doit disposer d’une configuration d’environnement claire pour l’API.
  • Le backend doit comprendre host, scheme et présence du proxy.
  • Azure doit être considéré comme une couche réelle de l’architecture, pas comme un tuyau neutre.
  • Les cookies doivent suivre le flux réel, pas sa représentation locale.
  • CORS doit viser précisément les domaines publics, pas être assoupli « pour que ça marche ».
  • Les journaux doivent montrer ce que le système voit réellement, pas les hypothèses de l’équipe.

C’est alors que la maturité de production prend forme.

La leçon essentielle

L’architecture échoue aussi sur de petites hypothèses mal comprises :

  • mauvais host,
  • mauvais scheme,
  • ordre incorrect des middlewares,
  • politique de cookies inadaptée,
  • idée erronée qu’Azure ne change rien,
  • confiance excessive dans le fonctionnement local.

Le défaut paraît d’abord une anomalie mineure. On découvre ensuite qu’il gouverne connexion, routage, callbacks, sécurité et stabilité de toute la plateforme.

Conclusion

Frontend, backend et Azure peuvent être correctement conçus séparément et former malgré tout un ensemble instable. La production exige la cohérence en plus du bon code.

Toutes les couches doivent partager la même compréhension. Même host, même scheme, mêmes règles de confiance, même sémantique de sécurité et même représentation de la requête.

Une petite erreur peut décider si l’utilisateur voit une plateforme professionnelle ou un système qui ne tient que jusqu’au premier déploiement délicat.