HTTP code 401 Unauthorized : causes, solutions et bonnes pratiques

David
http code 401

Le redouté HTTP 401 Unauthorized a le chic pour interrompre la navigation, casser vos appels API et saturer votre support. La bonne nouvelle ? Parce que ce statut est strictement défini par la norme, il se dompte très bien quand on sait où regarder.

Au fil de ce guide, nous allons voir ce que cache réellement un 401, comment le traquer (logs, DevTools, cURL) et surtout les actions concrètes pour le faire disparaître côté client comme côté serveur. En prime, vous y trouverez quelques idées pour muscler la sécurité de vos applis web et de vos API REST.

Erreur HTTP 401 : comprendre le code « Unauthorized »

1. Qu’est-ce que le code HTTP 401 ? Définition claire

Le 401 Unauthorized appartient à la famille des 4xx. En clair, le serveur dit :

« Je n’exécute pas cette requête ; il me manque des identifiants valides. »

Traduction pratique :

  • la ressource est protégée ;
  • le serveur réclame une authentification ;
  • les informations d’authentification sont absentes, fausses ou périmées.

On parle bien ici d’authentification (AuthN) ; la question de l’autorisation (AuthZ) viendra plus tard.

2. Origine du statut 401 dans la norme RFC 7235

Tout est écrit noir sur blanc dans la RFC 7235 (HTTP/1.1 : Authentication). Ce texte définit :

  • quand on doit renvoyer un 401 Unauthorized ;
  • comment utiliser l’en-tête WWW-Authenticate ;
  • les schémas d’authentification (Basic, Digest, Bearer, etc.).

Au passage, la RFC précise qu’une réponse 401 doit contenir au moins un header WWW-Authenticate expliquant au client comment s’authentifier.

3. Différence entre 401, 403 et autres codes 4xx

La question revient souvent : pourquoi 401 plutôt que 403 ?

  • 401 Unauthorized : le client n’est pas authentifié ou l’est mal.
    • Ex. : token absent, expiré ou mot de passe incorrect.
  • 403 Forbidden : l’utilisateur est bien authentifié, mais n’a pas les droits.
    • Ex. : connecté sans le rôle « admin » pour /admin.

Pour mémoriser : 401 = besoin d’authentification ; 403 = authentifié mais pas autorisé.

D’autres 4xx peuvent prêter à confusion :

  • 400 Bad Request : requête mal formée ;
  • 404 Not Found : ressource introuvable ;
  • 429 Too Many Requests : trop de requêtes en un temps donné.

4. Rôle du header WWW-Authenticate

Pour être conforme, une réponse 401 embarque un WWW-Authenticate qui :

  • précise le type d’authentification (Basic, Bearer…) ;
  • fournit des détails (realm, erreur, description) ;
  • indique au client comment retenter sa chance.

Exemple en Basic Auth :

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Admin Area"
Content-Type: text/plain

401 Unauthorized

Ou en Bearer / OAuth 2.0 :

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api",
 error="invalid_token",
 error_description="The access token is expired"

{"error":"invalid_token","error_description":"Token expired"}

1. Les causes courantes d’une erreur HTTP 401

1.1 Identifiants manquants ou invalides

Ne tournons pas autour du pot : la majorité des 401 vient tout simplement d’un problème d’identifiants.

  • pas de header Authorization ;
  • header mal formé ;
  • mauvais login/mot de passe ;
  • clé API inconnue du serveur.

Illustrations :

GET /api/secure-data HTTP/1.1
Host: api.example.com
# Pas d'Authorization
GET /api/secure-data HTTP/1.1
Host: api.example.com
Authorization: Bearer abc   # Token incomplet

1.2 Token ou session expiré

Les API reposent souvent sur des access tokens (OAuth 2.0, JWT) qui ont une durée de vie limitée. Une fois expirés, c’est le 401 assuré.

On voit régulièrement :

  • un JWT dont la claim exp est dépassée ;
  • une session invalidée côté serveur (logout, rotation de clés) ;
  • un cookie de session périmé côté navigateur.
WWW-Authenticate: Bearer error="invalid_token",
 error_description="Access token expired"

1.3 Mauvaise configuration du serveur ou du reverse proxy

Parfois, l’erreur vient de l’infrastructure :

  • Apache, Nginx ou IIS mal configuré ;
  • reverse proxy qui filtre ou écrase Authorization ;
  • CDN qui sert une vieille réponse 401 ;
  • WAF un peu trop zélé.

Exemple classique : Nginx ne transmet pas le header Authorization au backend ; l’appli pense que le client n’est pas authentifié et répond 401.

2. Comment diagnostiquer une erreur 401 pas à pas

2.1 Analyse des logs serveur (Apache, Nginx, IIS)

Premier réflexe : les logs.

Apache

  • Access : /var/log/apache2/access.log
  • Error : /var/log/apache2/error.log
grep " 401 " /var/log/apache2/access.log | tail -n 50

Regardez la ressource, l’IP, le user-agent, le module d’auth.

Nginx

  • Access : /var/log/nginx/access.log
  • Error : /var/log/nginx/error.log
grep " 401 " /var/log/nginx/access.log | tail -n 50

Focus sur : auth_basic, auth_request, et la transmission du header.

IIS

  • Logs par défaut : C:\inetpub\logs\LogFiles
  • Activez les sous-codes 401 (401.1, 401.2…).

Les sous-codes dévoilent la vraie raison du refus.

2.2 Inspection des requêtes HTTP (DevTools, cURL, Postman)

Ensuite, on regarde la requête et la réponse réelles.

Dans le navigateur

  • DevTools (F12) ;
  • onglet Network ;
  • rechargez la page ;
  • inspectez Headers et Response.

Le header Authorization est-il présent ? Quel est le WWW-Authenticate ? Les cookies sont-ils envoyés ?

Avec cURL

curl -i https://api.example.com/secure-resource
curl -i https://api.example.com/secure-resource \
  -H "Authorization: Bearer <ACCESS_TOKEN>"
curl -v https://api.example.com/secure-resource

PowerShell

$headers = @{ "Authorization" = "Bearer <ACCESS_TOKEN>" }
Invoke-WebRequest -Uri "https://api.example.com/secure-resource" `
  -Headers $headers -Method GET -Verbose

2.3 Tests de l’en-tête d’authentification

Trois points à vérifier : schéma, construction, transmission jusqu’au backend.

Basic Auth

Authorization: Basic <base64(username:password)>
curl -i https://example.com/admin -u "admin:monMotDePasse"

Bearer token

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token",
 error_description="Invalid signature"

3. Solutions côté client : corriger l’erreur 401 pour les utilisateurs

3.1 Vider le cache et les cookies

Sur un site web, un 401 peut venir simplement de :

  • cookies de session corrompus ;
  • token périmé dans le localStorage ;
  • cache qui sert une page protégée.

Le trio gagnant : on supprime cookies et données de site, on vide le cache, on se reconnecte.

3.2 Vérifier l’URL protégée et la session

Vous vous demandez « Mais pourquoi ce 401 ? ». Souvent, la réponse est simple : vous n’êtes plus connecté.

Pensez à contrôler :

  • la présence d’une session active ;
  • la justesse de l’URL (copier-coller trompeur ?) ;
  • les redirections automatiques vers la page de connexion.

Côté UX, mieux vaut afficher une page explicite : « Votre session a expiré, veuillez vous reconnecter » plutôt qu’un laconique « 401 Unauthorized ».

3.3 Renouveler ou rafraîchir le token d’accès

Avec OAuth 2.0/JWT, les access tokens vivent peu de temps (10–30 min). Une fois expirés, ils déclenchent un 401.

Le remède ? Le flux refresh :

  1. envoyer la requête de refresh token ;
  2. remplacer l’ancien token ;
  3. rejouer la requête échouée.
POST /oauth/token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=<REFRESH_TOKEN>&client_id=<CLIENT_ID>

4. Solutions côté serveur : sécuriser et configurer correctement l’authentification

4.1 Mettre en place Basic, Digest ou Bearer Auth

Trois grands classiques :

  • Basic Auth : redoutablement simple, à chiffrer via HTTPS.
  • Digest : plus sûr que Basic, mais rarement employé aujourd’hui.
  • Bearer : tokens (souvent JWT), standard des API REST.

Apache + Basic Auth

<Directory "/var/www/html/admin">
  AuthType Basic
  AuthName "Admin Area"
  AuthUserFile /etc/apache2/.htpasswd
  Require valid-user
</Directory>

Nginx + Basic Auth

location /admin/ {
  auth_basic           "Admin Area";
  auth_basic_user_file /etc/nginx/.htpasswd;
}

Middleware Bearer (Express.js)

app.use('/api', (req, res, next) => {
  const auth = req.headers['authorization'];
  if (!auth || !auth.startsWith('Bearer ')) {
    return res.status(401)
      .set('WWW-Authenticate',
        'Bearer realm="api", error="invalid_request",' +
        ' error_description="Missing Bearer token"')
      .json({ error: 'unauthorized' });
  }
  const token = auth.slice(7);
  // Vérification du token...
  next();
});

4.2 Configurer OAuth 2.0 / JWT dans une API REST

Le triptyque gagnant : obtenir un token, l’envoyer dans Authorization: Bearer, le valider (signature, audience, expiration, scopes).

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="example",
 error="invalid_token",
 error_description="The access token expired"

{"error":"invalid_token","error_description":"The access token expired"}

À surveiller : signature, exp, aud, scopes. Une clé tournée sans préavis = tsunami de 401 !

4.3 Gérer les expirations de session et les rafraîchissements de tokens

Tout est affaire de timing.

  • Sessions web : 30 min d’inactivité, rafraîchies si l’utilisateur reste actif.
  • Access tokens : 5 à 30 min, avec refresh token pour prolonger.

Quand la session expire, le serveur répond 401 de façon claire afin que le client déclenche le bon flux de renouvellement.

5. Bonnes pratiques pour éviter les erreurs 401 à l’avenir

5.1 Stratégies de rotation de mots de passe et de tokens

Trouvez le juste milieu : sécuriser sans mitrailler vos utilisateurs de 401.

  • Rotation des mots de passe raisonnable, pas tous les 30 jours.
  • Rotation des clés de signature JWT (via kid) pour une transition douce.
  • Limiter la durée de vie des tokens pour réduire les risques en cas de fuite.

5.2 Monitoring et alerting des codes 4xx

Un pic de 401 peut révéler un bug frontal, un IdP en rade… ou une attaque.

  • Dashboards Prometheus, Grafana, ELK, Datadog…
  • Alertes dès qu’un seuil de 401 est dépassé.
  • Corrélation par IP, user, client_id pour flairer l’anomalie.

5.3 Tests automatisés d’authentification en CI/CD

Glissez des tests d’auth dans vos pipelines et dormez tranquille.

  • Unitaires : le middleware lâche un 401 quand il faut ;
  • Intégration : cURL, Postman ou Newman pour vérifier chaque endpoint protégé ;
  • Cas limites : token expiré, signature invalide, absence de header…

6. Scénarios typiques et tableau récapitulatif d’erreurs 401

6.1 Scénarios liés au client, serveur, proxy / CDN

Un coup d’œil à ce tableau pour orienter le diagnostic :

Scénario Symptômes Cause probable Action
Mot de passe incorrect 401 immédiat après login Identifiants invalides Vérifier user/pass, réinitialiser le mot de passe
Token expiré 401 après quelques minutes Access token hors délai Implémenter ou réparer le refresh token
Authorization absent 401 via un reverse proxy Header filtré par le proxy Configurer proxy_set_header Authorization
HTTP → HTTPS 401 sporadiques Cookies non envoyés / invalides Forcer HTTPS, ajouter l’attribut Secure
CDN / cache 401 même après login 401 mis en cache par erreur Désactiver le cache ou Vary: Authorization

6.2 Cas réels avec reverse proxy et CDN

Scénario Nginx : le backend attend Authorization, Nginx l’oublie.

location /api/ {
    proxy_pass http://backend;
    # header Authorization non transmis
}

La rustine :

location /api/ {
    proxy_pass http://backend;
    proxy_set_header Authorization $http_authorization;
}

Côté CDN, si /api/me est mis en cache et renvoie 401 une fois, tous les suivants y auront droit. Filtrez ou désactivez le cache sur les routes sensibles, ou servez-les avec Vary: Authorization.

7. Check-list sécurité & conformité (GDPR, PCI-DSS)

7.1 Ne jamais exposer d’informations sensibles dans une 401

Une 401 doit rester sobre : pas de nom, pas d’email, pas d’aveu « l’utilisateur existe ». L’info détaillée reste dans les logs, le client reçoit un message générique, le tout en HTTPS.

7.2 Bonnes pratiques UX pour masquer le « 401 Unauthorized » brut

Pour éviter l’écran qui fait peur :

  • API : répondez en JSON propre : {"error":"unauthorized","message":"Authentication required"}.
  • Appli web : interceptez le 401, redirigez vers /login ou affichez « Session expirée ».

8. FAQ sur l’erreur HTTP 401

8.1 C’est quoi l’erreur 401 ? Que signifie le texte « 401 Unauthorized » ?

Un 401 signale que la ressource est protégée et que vos identifiants manquent ou sont invalides. « 401 Unauthorized » est le libellé officiel qui vous intime de (re)passer par la case authentification.

8.2 Comment résoudre l’erreur 401 ? (non autorisé)

Deux angles d’attaque :

  • Côté utilisateur : vérifier identifiants ou token, se reconnecter, nettoyer cache/cookies.
  • Côté dev ou admin : plonger dans les logs, inspecter les headers, ajuster la conf d’auth/proxy.

8.3 Mon site renvoie 401 alors que mes identifiants sont bons. Pourquoi ?

Pistes courantes : token expiré, compte désactivé, backend mal configuré ou header modifié par un proxy. Testez avec cURL ou Postman et inspectez les logs pour lever le doute.

8.4 Comment forcer la redirection vers la page de connexion ?

Recette habituelle :

  • Pour une API : garder le 401 et un JSON d’erreur.
  • Pour une webapp : intercepter le 401 et répondre par une 302 vers /login ou une page HTML qui redirige.
app.use((err, req, res, next) => {
  if (err.name === 'UnauthorizedError') {
    if (req.accepts('html')) {
      return res.redirect('/login');
    }
    return res.status(401).json({ error: 'unauthorized' });
  }
  next(err);
});

8.5 Une même requête peut-elle renvoyer 401 puis 403 ?

Une requête = un seul code. Vous pouvez recevoir 401, puis, après authentification, un 403 sur une autre requête si l’accès reste interdit. Mais pas les deux en même temps.

Conclusion : maîtriser le HTTP 401 pour des applications plus robustes

Le 401 Unauthorized n’est pas un simple caillou dans la chaussure ; c’est un indicateur précieux d’un souci d’authentification. En comprenant sa définition (RFC 7235, WWW-Authenticate), en distinguant 401 et 403, en repérant les causes (identifiants, tokens, proxy, CDN) et en appliquant les bonnes pratiques OAuth 2.0/JWT, vous réglerez rapidement le problème et réduirez le nombre de tickets support.

Prochaine étape : automatisez vos tests (cURL, Postman, tests d’intégration) pour chaque endpoint protégé :

  • absence de credentials → 401 attendu ;
  • auth correcte → accès autorisé ;
  • réponse 401 claire + header WWW-Authenticate.

C’est un petit effort aujourd’hui qui vous évitera bien des sueurs froides lorsque le prochain « 401 Unauthorized » surgira dans vos logs.

Questions fréquentes sur le code HTTP 401

C’est quoi l’erreur 401 ?

L’erreur HTTP 401, ou « Unauthorized », indique que le serveur refuse la requête car des identifiants valides sont absents, incorrects ou expirés. Elle nécessite une authentification pour accéder à la ressource demandée.

Comment résoudre l’erreur 401 (non autorisé) ?

Pour résoudre une erreur 401, vérifiez vos identifiants (login, mot de passe, token). Assurez-vous que le token ou la session n’est pas expiré et que le header Authorization est correctement configuré. Si le problème persiste, examinez les logs serveur ou contactez l’administrateur.

Que signifie le code HTTP 401 ?

Le code HTTP 401 signifie que le client n’est pas authentifié ou que ses informations d’authentification sont invalides. Il est souvent accompagné d’un header « WWW-Authenticate » pour guider le client sur la méthode d’authentification requise.

Quelle est la différence entre les codes HTTP 401 et 403 ?

Le code 401 indique un problème d’authentification (identifiants absents ou invalides), tandis que le code 403 signifie que l’utilisateur est authentifié mais n’a pas les permissions nécessaires pour accéder à la ressource.

Pourquoi le header WWW-Authenticate est-il important dans une réponse 401 ?

Le header WWW-Authenticate est essentiel car il informe le client sur le type d’authentification requis (Basic, Bearer, etc.) et fournit des détails pour corriger l’erreur, comme le realm ou la description d’une erreur spécifique.

Quels sont les cas courants où une erreur 401 se produit ?

Les erreurs 401 surviennent souvent à cause d’identifiants manquants ou invalides, de tokens expirés, ou d’une mauvaise configuration du serveur ou du reverse proxy. Vérifiez ces éléments pour identifier la source du problème.

toshare

ToShare à Saint-Tropez : menu, prix, avis et coulisses

Pourquoi tout le monde ne parle-t-il soudain que de ToShare à Saint-Tropez ? Signé par l’inattendu tandem Jean Imbert – Pharrell Williams, l’endroit revisite l’art ...
David
wasl 1880

Wasl 1880 : histoire, menu, prix et secrets d’un mythe parisien

Et si un simple dîner devenait une promenade dans le Paris de la Belle Époque ? Wasl 1880, longtemps resté confidentiel avant d’être adopté ...
David

Laisser un commentaire